题意:对于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)(mod 2^k) 此方程为 模线性方程,本题就是求x的值。
即求模线性方程 ax=b mod n的解。 其中a=C,b=B-A,n=2^K.
该方程有解的充要条件为 gcd(a,n) | b ,即 b% gcd(a,n)==0
令d=gcd(a,n)有该方程的 最小整数解为 x0 = X (mod n/d)
X为任意解,x0为最小整数解
#include<stdio.h> __int64 exgcd(__int64 a,__int64 b,__int64 &x,__int64 &y) //扩展欧几里得 { __int64 t,d; if(b==0){ x=1; y=0; return a; } d=exgcd(b,a%b,x,y); t=x; x=y; y=t-a/b*y; return d; } int main() { __int64 A,B,C,k,a,b,n,d,x,y; while(scanf("%I64d%I64d%I64d%I64d",&A,&B,&C,&k)!=EOF){ if(A==0&&B==0&&C==0&&k==0) break; a=C; b=B-A; n=(__int64)1<<k; //1要转化为64位 d=exgcd(a,n,x,y); if(b%d){ //若方程无解,则会一直循环 printf("FOREVER\n"); continue; } x=x*(b/d)%n; x=(x%(n/d)+(n/d))%(n/d); //求最小正解 printf("%I64d\n",x); } return 0; }
时间: 2024-10-13 16:05:41