扩展欧几里得算法(双六游戏)

题目大意:一个双六上面有向前 向后无限延续的格子, 每个格子都写有整数。其中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;
}

 

posted @ 2018-08-06 11:14  执||念  阅读(609)  评论(0编辑  收藏  举报