您的位置:首页 > 其它

2016.10.07【初中部 NOIP提高组 】模拟赛C题解

2016-10-13 12:00 190 查看
T1:

题目大意:就是通过某些水水水的计算求出最短路。然而细心的人可以发现,其实这道题的最短路形状(大概)是一模一样的。但是有个直线方程:

ax+by+c=0

ax+by=-c

两种情况:

1、已知a,b,c,x求y就是y=(-c-ax)/b

        2、已知a,b,c,y求x就是x=(-c-by)/a

        路径有4种情况,推出来后求最短的输出即可。注意细节。

T2:

这道题so因缺思厅。之前见过类似的题目,但是这道题的题目的确神奇:

           序列的中的数两两不同。每次可以交换序列中的任意两个数,代价为这两个数之和。将整个序列升序排序需要的最小代价是多少?

    因为排序是有最终序列的,所以数列中每一个数,都会在某一个环里面。

    也就是说,一个数到达它对应的点,然后对应的点又要去他那个到达的点里面,如此循环构成一个环。

    通过上面可以想到,可以用环中一个最小的数进行替换,因为最小的数跟一个数替换,那个数到了点,所得的花费也是最小加当前的数。如此交换,最终都到达了终点。

    不要高兴太早233333,还有个情况,如果环中的数都很大,怎么办?

    可以用序列的最小值与环中的最小值交换一下位置,然后用环中的最小值去替,最后把两个数还原,就可以了。

    因为最小值去替是最优的,所以正确性是必然的。

T3:

   第三题真是大大大大大难(shui)题,不过还是很难2333.

   我们需要明白两个性质:

    1、题目中,每一个段所构成的gcd结果,最多不会超过log(a[i])个,然而a[i]<=10^12。对于一个a[i],可以与他构成gcd的,只有他自己或者他的约数。

    2、当gcd的数相同时,我们取最左边的那个。多取和少取的gcd一样,为什么不乘多点呢?

    因为gcd数不超过log(a[i]),我们就可以用数组存那些gcd数,然后用这些数去和当前的a[i]更新。显然是正确的,因为这是一个连续的段。但是可能会超时,gcd数很多都是重复的,所以要去重。

    效率(T*nlogn)。还有动态规划,详见楼上。

T4:


   最后一道题那个不做显然是没什么卵用的2333.

            所以我们只考虑分裂和加一。

            所以,思考得出一个结论,先分裂后加比先加在分裂要来的更厉害一些,次数自然少。所以,我们就可以倒过来做:有0合并,非0就-1,举个例子吧:

0 3 0 3 0

1、0 2 0 2

2、0 1 1

3、0 0 0

4、0 0

5、0

     倒过来做也不是那么容易的。这里有个巧妙的方法,零的分裂有个公式(n+1) div 2,那么,我们不鸟-1,我们只考虑0。数i是不是到第i个数为0?所以我们可以统计x出现了几次,然后每次累加0,直到只有1个0,为止。

Code by fyj pascal:

for i:=0 to max do
begin
inc(num,a[i]);//累加0
num:=(num+1) div 2;//合并
inc(ans);//累加次数
end;
while num>1 do//可能到达第i时刻没清完,所以还要继续neng。。Mdzz
begin
inc(ans);
num:=(num+1) div 2;
end;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: