题目详情 编程语言中比较常见的是C循环,例如C语言 (C++,java也类似): for (unsigned i = A; i != B; i += C) ; 表示i从A开始,只要不等于B,每次加C。 我们的目标是计算这个循环执行的次数。 假设我们的整数都是无符号的,计算机支持的int是k位的。(即所有整数都是非负并且小于2^k的,并且所有 运算都对2^k取余数)。 输入格式 多组数据,每组数据占一行,包含4个整数A,B,C,k。(1<=k<=32, 0<=A,B,C<2^k)。 输出格式 对每组数据,输出一行,包含其循环次数,如果是死循环,输出-1。 答题说明 输入样例 3 3 2 16 3 7 2 16 7 3 2 16 3 4 2 12 输出样例 0 2 32766 -1 思路: 假设循环次数为x, 则有(A + x * C)% 2^k = B, 即存在y, 有 A + x * C = y * 2^k + B, 得到 x * C - y * 2^k = B - A, 该等式的形式为x * a + y * b = c, 这就是扩展欧几里得, 最后求出来的x要保证 大于等于0. 代码如下: #include <iostream> #include <climits> #include <ctime> #include <cmath> #include <algorithm> #include <cstdio> #include <stack> using namespace std; __int64 pow2[33]; void init() { pow2[0] = 1; for(int i=1; i<=32; i++) pow2[i] = pow2[i-1] * 2; } __int64 exgcd(__int64 a, __int64 b, __int64 &x, __int64 &y) { if(b == 0) { x = 1; y = 0; return a; } else { __int64 res = exgcd(b, a%b, x, y); __int64 t = x; x = y; y = t - a/b * y; return res; } } int main() { init(); __int64 a, b, c, k; while(scanf("%lld%lld%lld%lld", &a, &b, &c, &k)!=EOF) { __int64 x, y; __int64 gcd = exgcd(pow2[k], c, y, x); if((b-a)%gcd != 0) { printf("-1\n"); } else { x = x * ((b - a) / gcd); if(x >= 0) printf("%lld\n", x%(pow2[k]/gcd)); else { printf("%lld\n", pow2[k]/gcd - (-x)%(pow2[k]/gcd)); } } } return 0; }