PKU 1061-取石子游戏
問題概要
x+mk=y+nk (mod L)を満す最小のKを求めよ.存在しない場合"Impossible"って出力せよ.
解法
式変形して1次合同方程式を解く
蟻本p260参照
実装(C++)
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; typedef long long lli; lli x,y,m,n,L; long long extgcd(long long a,long long b,long long &x,long long &y){ long long d=a; if(b!=0){ d=extgcd(b,a%b,y,x); y-=(a/b)*x; }else{ x=1;y=0; } return d; } long long mod_inverse(long long a,long long M){ long long x,y; extgcd(a,M,x,y); return (M+x%M)%M; } lli solve(lli a,lli b,lli M){ lli t=__gcd(a,M); if(b%t!=0)return -1; a/=t;b/=t;M/=t; return mod_inverse(a,M)*b%M; } int main() { cin>>x>>y>>m>>n>>L; m-=n; x=y-x; x=(x+L)%L; m=(m+L)%L; if(m==0){ cout<<"Impossible"<<endl; return 0; } lli ans=solve(m,x,L); if(ans==-1){ cout<<"Impossible"<<endl; }else{ cout<<ans<<endl; } return 0; }