扩展欧几里得算法,同余方程。题意:C风格的for循环语句是这样的,
for (variable = A; variable != B; variable += C)
假设A、B和C在计算机中都是k位无符号整数,现在问这个for循环语句会执行几次循环。
解题思路:既然是k位无符号整数,那么假设循环n次,就有A + nC = B(mod 2^k),这是一个同余方程,我们可以转换成二元一次不定方程n*C + m*2^k = B - A,然后利用扩展欧几里得算法求n的最小正整数解就行了。
解题代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <limits.h>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
LL A, B, C, k;
LL ExGcd(LL a, LL b, LL &x, LL &y);
void DataProcess();
int main()
{
while (~scanf("%lld %lld %lld %lld", &A, &B, &C, &k))
{
if (A == 0 && B == 0 && C == 0 && k == 0) break;
DataProcess();
}
return 0;
}
LL ExGcd(LL a, LL b, LL &x, LL &y)
{
if (b == 0)
{
x = 1; y = 0;
return a;
}
LL g = ExGcd(b, a % b, y, x);
y -= x * (a / b);
return g;
}
void DataProcess()
{
LL x, y;
LL a = C;
LL b = 1LL << k;
LL c = B - A;
LL g = ExGcd(a, b, x, y);
if (c % g != 0)
{
puts("FOREVER");
return;
}
x *= c / g;
LL tmp = b / g;
printf("%lld\n", (x % tmp + tmp) % tmp);
return;
}