C Looooops
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions:33752 | Accepted: 9832 |
Description
A Compiler Mystery: We are given a C-language style for loop of type
for (variable = A; variable != B; variable += C) statement;
I.e., a loop which starts by setting variable to value A and while variable is not equal to B, repeats statement followed by increasing the variable by C. We want to know how many times does the statement get executed for particular values of A, B and C, assuming that all arithmetics is calculated in a k-bit unsigned integer type (with values 0 <= x < 2k) modulo 2k.
Input
The input consists of several instances. Each instance is described by a single line with four integers A, B, C, k separated by a single space. The integer k (1 <= k <= 32) is the number of bits of the control variable of the loop and A, B, C (0 <= A, B, C < 2k) are the parameters of the loop.
The input is finished by a line containing four zeros.
Output
The output consists of several lines corresponding to the instances on the input. The i-th line contains either the number of executions of the statement in the i-th instance (a single integer number) or the word FOREVER if the loop does not terminate.
Sample Input
3 3 2 16 3 7 2 16 7 3 2 16 3 4 2 16 0 0 0 0
Sample Output
0 2 32766 FOREVER翻译:在循环里,values值为a,每次加c,如果values不等于b,就继续循环下去,死循环输出forever,否则输出循环次数。所有运算都对无符号的k位二进制求模。解题过程:设p=2^k起点为a,每次加c,对p求模若能等于b对p求模则有解,否则无解,输出forever有解的话设解为x(a+cx)%p = b%pa%p + cx%p = b%pcx%p = (b-a)%pcx%p + 0 = (b-a)%pcx%p + yp%p = (b-a)%p形如ax+by=gcd,扩展欧几里得定理。
1 #include<stdio.h> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<math.h> 6 #include<string> 7 #define ll long long 8 #define inf 0x3f3f3f3f 9 using namespace std; 10 // ax + by = gcd(a,b) 11 ll exgcd(ll a, ll b, ll &x, ll &y)//扩展欧几里德定理 12 { 13 if(b==0)//终有一次a%b传进来是0,递归出口 14 { 15 x=1; 16 y=0; 17 return a; 18 } 19 ll q=exgcd(b,a%b,y,x); 20 //最终递归出来,y1=1,x1=0 21 y=y-(a/b)*x; 22 //后面的y相当于下一个递归的x2,x相当于下一个递归的y2,符合推导公式 23 //x1=y2; y1=x2-[a/b]*y2; 24 return q; 25 } 26 27 int main() 28 { 29 ll a,b,c,k,p,x,y; 30 while(scanf("%lld %lld %lld %lld",&a,&b,&c,&k)!=EOF&&(a+b+c+k)) 31 { 32 p=1; 33 for(ll i=1;i<=k;i++) 34 p=p*2; 35 ll gcd=exgcd(c,p,x,y); 36 ll d=b-a; 37 if(d%gcd) 38 printf("FOREVER\n"); 39 else 40 { 41 ll multiple=d/gcd;///倍数 42 p=p/gcd;///通解公式:x=x+b/gcd y=y-a/gcd 43 x=( (x*multiple)%p+p )%p;///求最小正数解 44 printf("%lld\n",x); 45 } 46 } 47 return 0; 48 }
原文地址:https://www.cnblogs.com/shoulinniao/p/10361943.html