POJ2115 C Looooops 扩展欧几里德
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - POJ2115
题意
对于C的for(i=A ; i!=B ;i +=C)循环语句,问在k位存储系统中循环几次才会结束。若在有限次内结束,则输出循环次数。否则输出死循环。
题解
原题题意再次缩略:
A + xC Ξ B (mod 2k)
求x的最小正整数值。
我们把式子稍微变一下形:
Cx + (2k)y = B-A
然后就变成了一个基础的二元一次方程求解,扩展欧几里德套套就可以了。
至于扩展欧几里德(ex_gcd),自己网上学习吧。
代码
#include <cstring> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cmath> using namespace std; typedef long long LL; LL A,B,C,k,a,b,c,x,y,g; LL ex_gcd(LL a,LL b,LL &x,LL &y){ if (!b){ x=1,y=0; return a; } LL gcd=ex_gcd(b,a%b,y,x); y-=(a/b)*x; return gcd; } int main(){ while (~scanf("%lld%lld%lld%lld",&A,&B,&C,&k)&&(A||B||C||k)){ k=1LL<<k; //A+xC=B (mod 2^k) //Cx+(2^k)y=B-A a=C,b=k,c=(B-A+k)%k; g=ex_gcd(a,b,x,y); if (c%g){ puts("FOREVER"); continue; } a/=g,c/=g,b/=g; x*=c,y*=c; x=(x%b+b)%b; printf("%lld\n",x); } return 0; }