题解 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各位~

原文地址:https://www.cnblogs.com/oierscw/p/12542224.html