LL exgcd(LL a,LL b,LL &x,LL &y)
{
LL r,t;
if(b==0)
{
x=1;
y=0;
return a;
}
r=exgcd(b,a%b,x,y);
t=x;
x=y;
y=t-a/b*y;
return r;
}
求a * x + b * y = c一组整数解的步骤:
1、计算g=gcd(a,b),如果c%g!=0,即c不能被g整除,则无整数解,不再继续下面的步骤。
特别的,如果已经知道a * x + b * y = c一定有解,可跳过这一步。
2、通过g=exgcd(a,b,x',y')(g为a、b最大公约数)得到方程a * x + b * y = gcd(a,b) =g的一组解x'、y';
3、x=x'*c/g、y=y'*c/g(不能先除后乘)得到方程a * x + b * y = c的一组特解x、y;
4、通过特解可得方程a * x + b * y = c的通解为:
题意:两个青蛙在赤道上跳跃,走环路。起始位置分别为x,y。每次跳跃距离分别为m,n。赤道长度为L。两青蛙跳跃方向与次数相同的情况下,问两青蛙是否有方法跳跃到同一点。输出最少跳跃次数。
分析:扩展欧几里德。设两青蛙跳了s步。有方程:(x+n*s)-(y+m*s)=k*L。整理得:(n-m)*s+L*(-k)=y-x.接下来只用按就方程ax+by=c的步骤写就行了。
#include<stdio.h>
__int64 exgcd(__int64 a,__int64 b,__int64 &x,__int64 &y)
{
__int64 r,t;
if(b==0)
{
x=1;
y=0;
return a;
}
r=exgcd(b,a%b,x,y);
t=x;
x=y;
y=t-a/b*y;
return r;
}
int main()
{
__int64 x,y,m,n,l,xx,yy,g,r;
scanf("%I64d%I64d%I64d%I64d%I64d",&x,&y,&m,&n,&l);
g=exgcd(n-m,l,xx,yy);
if((x-y)%g!=0) printf("Impossible\n");
else {
xx=xx*(x-y)/d;
r=l/d;
xx=(xx%r+r)%r;//求出最小非负整数解
printf("%I64d\n",xx);
}
return 0;
}
POJ 2115 C Looooops
对于C的for(i=A ; i!=B ;i +=C)循环语句,问在k位存储系统中循环几次才会结束。
若在有限次内结束,则输出循环次数。
否则死循环,输出FOREVER。
思路:
题意不难理解,只是利用了 k位存储系统 的数据特性进行循环。
例如int型是16位的,那么int能保存2^16个数据,即最大数为65535(本题默认为无符号),
当循环使得i超过65535时,则i会返回0重新开始计数
如i=65534,当i+=3时,i=1
其实就是 i=(65534+3)%(2^16)=1
据此我们得到方程c*x=(b-a)%2^k然后根据扩展欧几里得算法解就行了,不用b-a不是系数,所以不用考虑其正负
注意:k <=32 ,而 2^32超出整数范围,所以要用__int64或long long ,也就是LL B=(LL)1<<k
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int M = 100050;
typedef long long LL;
LL gcd( LL x,LL y )
{
return y ? gcd( y , x % y ) : x;
}
LL exgcd(LL a, LL b, LL & x, LL & y)
{
if (b == 0)
{
x=1;
y=0;
return a;
}
LL d = exgcd(b, a % b, x, y);
LL t = x;
x = y;
y = t - a / b * y;
return d;
}
int main(){
//freopen("in.txt","r",stdin);
LL a,b,c,k;
while(scanf("%lld%lld%lld%lld",&a,&b,&c,&k)!=EOF){
if(!(a||b||c||k)) break;
LL A=c,B=((LL)1<<k),C=b-a,g,x,y;
g=gcd(A,B);
if(C%g!=0)
printf("FOREVER\n");
else{
A/=g;B/=g;C/=g;
exgcd(A,B,x,y);
x*=C;
x=(x%B+B)%B;
cout<<x<<endl;
}
}
return 0;
}