ZOJ-3593 One Person Game(数论-扩展欧几里得)

ZOJ-3593 One Person Game(数论-扩展欧几里得)_第1张图片

ZOJ-3593 One Person Game(数论-扩展欧几里得)_第2张图片

题意

给一个起点A,一个终点B,

从起点出发,

每次可以选择向左或向右走a格,b格,或c格(c=a+b),

走一次记为一步,求A到B的最小步数,无法走到输入-1

思路来源

https://blog.csdn.net/yjf3151731373/article/details/70071941

题解

最后肯定是求ax+by=d,d=abs(B-A)

当d不能整除c=gcd(a,b)时,显然为-1,

 

令a/=c,b/=c,d/=c,等价于求a'x+b'y=d',gcd(a',b')=1

此时可用a'x+b'y=1求一组解x0,y0,

x0*=d,y0*=d即为一组原方程解x0',y0'

而原方程通解x=x0'+k*b',y=y0'-k*a',

 

当x与y同号时,答案为max(|x|,|y|);

当x与y异号时,答案为|x|+|y|;

 

显然,若x==y能成立,则任何其它解x1,y1都会增大其中一个的绝对值从而使答案更大,

所以如果x==y能成立,答案就是x==y,

此时有x0'+k*b'=y0'-k*a',k=(y0'-x0')/(a'+b')。

这就是一个凹函数,x==y的时候是拐点,

如果k是double的话,一定是取拐点,此时有极小值|x|步

 

其它情况下,不妨x

若x与y距离不是最小(即存在x1,y1,使得x

x1和y1这组解,无论是同号还是异号,都比x、y这组解更优。

 

但同样也有可能,x,y距离是当前最小了(但不是0)(却存在x1,y1,使得x

而x1,y1这组解更优,这其实是k无法取整从而使距离不能取到理论最小导致的。

若不能取拐点的话,离拐点最近的两个整点,都判一下就好了

k无法取整值,所以就要取距k最近的那两个整值判断一下哪个更小,

那就不妨直接枚举k-1,k,k+1,取最小

代码

#include 
#include 
#include 
#include 
const int maxn=3e3+10;
using namespace std;
typedef long long ll;
int t;
ll A,B,a,b; 
ll extgcd(ll a,ll b,ll &x,ll &y)
{
	ll d=a;
	if(b)d=extgcd(b,a%b,y,x),y-=(a/b)*x;
	else x=1,y=0;
	return d;
}
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		ll c,d,x,y,ans=1e18;
		scanf("%lld%lld%lld%lld",&A,&B,&a,&b);
		d=extgcd(a,b,x,y);
		if(A0)ans=min(ans,max(xxx,yyy));
			else ans=min(ans,xxx+yyy); 
		  }
		  printf("%lld\n",ans); 
	    }
	}
	return 0;
}

 

你可能感兴趣的:(数论,数论,extgcd,扩展欧几里得,One,Person,Game)