扩展欧几里得算法(双六游戏)
Posted caijiaming
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了扩展欧几里得算法(双六游戏)相关的知识,希望对你有一定的参考价值。
题目大意:一个双六上面有向前 向后无限延续的格子, 每个格子都写有整数。其中0号格子是起点,1号格子
是终点。而骰子上只有a,b,-a,-b四个整数,所以根据a和b的值的不同,有可能无法到达终点
掷出四个整数各多少次可以到达终点呢?如果解不唯一,输出任意一组即可。如果无解 输出-1
思路:这道题用数学方法表述就是求整数x和y使得“ax+by=1",可以发现,如果gcd(a,b)不等于1,显然无解。 反之,则可以用扩展欧几里得算法来求解。 事实上,一定存在整数对(x,y)使得ax+by=gcd(a,b)
具体看代码:
#include<iostream> #include<string.h> #include<map> #include<cstdio> #include<cstring> #include<stdio.h> #include<cmath> #include<math.h> #include<algorithm> #include<set> #include<queue> typedef long long ll; using namespace std; const ll mod=1e9+7; const int maxn=1e3+10; const int maxk=5e3+10; const int maxx=1e4+10; const ll maxe=1000+10; #define INF 0x3f3f3f3f3f3f #define Lson l,mid,rt<<1 #define Rson mid+1,r,rt<<1|1 int extgcd(int a,int b,int &x,int &y)//这里才是关键所在 { int d=a;//d 是最大公约数 if(b!=0) { d=extgcd(b,a%b,y,x);//之前一直在想为什么为什么是这样的,想了很久,下面看解释 /*刚开始是ax+by=gcd(a,b),但是按照这个算法来的话,下一步就变成了bx‘+(a%b)y‘=gcd(a,b) a%b=a-a/b*b,代入上面方程得到 ay‘+b(x‘-a/b*y‘)=gcd(a,b) 其实这里的y‘=x,x‘=y 所以可以得到x=y‘ y=y-(a/b*x) */ y-=a/b*x; } else { x=1;y=0; } return d;//每次都是返回最大公约数 } int main() { int a,b,x,y; int ans[4]={0}; cin>>a>>b; if(extgcd(a,b,x,y)!=1) cout<<"-1"<<endl; else { if(x<0) ans[2]=-x; else ans[0]=x; if(y<0) ans[3]=-y; else ans[1]=y; for(int i=0;i<4;i++) cout<<ans[i]; cout<<endl; } return 0; }
以上是关于扩展欧几里得算法(双六游戏)的主要内容,如果未能解决你的问题,请参考以下文章