题解 P2660 【zzc 种田】

这题是真呀,我打了一个普通算法一看:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    unsigned long long x,y;
    unsigned long long ans=0;
    cin>>x>>y;
    while(x!=0&&y!=0)
    {
        unsigned long long k=min(x,y);
        if(k==x) y-=k;
        else x-=k;
        ans+=4*k
    }
    cout<<ans;
    return 0;
}

然后就光荣地TLE了……(手动滑稽)

后来发现,这个算法有很大的剪枝空间,比如样例一,x=1,y=10,这个程序运行时各个变量如下:

x: 1  1 1 1  1  1  1  1  1  1  1

y:10  9 8 7  6  5  4  3  2  1  0

k: /  1 1 1  1  1  1  1  1  1  1

ans:0 4 8 12 16 20 24 28 32 36 40

里面有很多是重复计算的,比如对于这个样例,我们可以这么算:y是x的10/1=10倍,所以这个k只要算出后乘十就行。

代码如下

#include<bits/stdc++.h>
using namespace std;
int main()
{
    unsigned long long x,y;
    unsigned long long ans=0;
    cin>>x>>y;
    while(x!=0&&y!=0)
    {
        if(x<y) 
        {
            x^=y; y^=x; x^=y;
        } 
        unsigned long long k=x/y,t=0;
        t=k*y;
        ans+=t*4;
        x-=t;
    }
    cout<<ans;
    return 0;
}

886各位~

猜你喜欢

转载自www.cnblogs.com/oierscw/p/12542224.html
今日推荐