题目:
A Compiler Mystery: We are given a C-language style for loop of type
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
题意:
初始值为A,每次可以增加C,值要mod2^k^,问mod后的值如果等于B,增加了几次C,如果无法等于B输出FOREVER
题解:
看一下我的推导:
你会发现其实就是扩展欧几里得的模板题,并求出最小正整数解
我们可以用 (x0 % b1 + b1 ) % b1得到它的最小正整数解了
此处x0= x * c / gcd(a,b)
详细证明看下面博客
扩展欧几里得讲解
代码:
#include<iostream> #include<vector> #include<string> #include<cmath> #include<algorithm> #include<cstdio> #include<cstring> #include<list> using namespace std; typedef long long ll; ll exgcd(ll a,ll b,ll &x,ll &y)//扩展欧几里得算法 { if(b==0) { x=1; y=0; return a; //到达递归边界开始向上一层返回 } ll gcd=exgcd(b,a%b,x,y); ll y1=y; //把x y变成上一层的 ll x1=x; y=x1-(a/b)*y1; x=y1; return gcd; //得到a b的最大公因数 } int main() { ll A,B,C,K; while(cin>>A>>B>>C>>K) { if(A==0&&B==0&&C==0&&K==0)break; ll x,y; ll a=C; ll b=(ll)1<<K; ll c=B-A; ll gcd=exgcd(a,b,x,y); if(c%gcd!=0) { cout<<"FOREVER"<<endl; } else { x=(x*(c/gcd))%b; x=(x%(b/gcd)+b/gcd)%(b/gcd); cout<<x<<endl; } } return 0; }