poj 2115 C Looooops (扩展欧几里得算法)

来源:互联网 发布:网络电视怎样看中央台 编辑:程序博客网 时间:2024/05/18 01:37
题意:对于C的for(i=A ; i!=B ;i +=C)循环语句,问在k位存储系统中循环几次才会结束。

若在有限次内结束,则输出循环次数。

否则输出死循环。


思路:题意不难理解,只是利用了 k位存储系统的数据特性进行循环。

例如int型是16位的,那么int能保存2^16个数据,即最大数为65535(本题默认为无符号),

当循环使得i超过65535时,则i会返回0重新开始计数

如i=65534,当i+=3时,i=1

其实就是i=(65534+3)%(2^16)=1

有了这些思想,设对于某组数据要循环x次结束,那么本题就很容易得到方程:

x=[(B-A+2^k)%2^k] /C

即 Cx=(B-A)(mod2^k)  此方程为 模线性方程,本题就是求X的值。


参考资料:

http://www.acmerblog.com/extend-gcd-5610.html

http://blog.csdn.net/lyy289065406/article/details/6648546

#include <iostream>#include <stdio.h>using namespace std;//d=ax+by,其中最大公约数d=gcd(a,n),x、y为方程系数,返回值为d、x、y__int64 EXTENDED_EUCLID(__int64 a,__int64 b,__int64& x,__int64& y){if(b==0){x=1;y=0;return a;  //d=a,x=1,y=0,此时等式d=ax+by成立}__int64 d=EXTENDED_EUCLID(b,a%b,x,y);__int64 xt=x;x=y;y=xt-a/b*y;  //系数x、y的取值是为满足等式d=ax+byreturn d;}int main(void){__int64 A,B,C,k;while(scanf("%I64d %I64d %I64d %I64d",&A,&B,&C,&k)){if(!A && !B && !C && !k)break;__int64 a=C;__int64 b=B-A;__int64 n=(__int64)1<<k;  //2^k__int64 x,y;__int64 d=EXTENDED_EUCLID(a,n,x,y);  //求a,n的最大公约数d=gcd(a,n)和方程d=ax+by的系数x、yif(b%d!=0)  //方程 ax=b(mod n) 无解cout<<"FOREVER"<<endl;else{x=(x*(b/d))%n;  //方程ax=b(mod n)的最小解x=(x%(n/d)+n/d)%(n/d);  //方程ax=b(mod n)的最整数小解printf("%I64d\n",x);}}return 0;}
0 0