题目概述:
数字a,若不等于b,则加c,当a大于2的k次方时便减去2的k次方
输入:
每行a,b,c,k,多组数据之间没有空行
限制:
0<=a,b,c<2^k
输出:
若能到b,输出加的最少次数,否则输出FOREVER
样例输入:
3 3 2 4
3 7 2 4
7 3 2 4
3 4 2 4
0 0 0 4
0 0 0 0
样例输出:
0
2
6
FOREVER
0
讨论:
这个题额想到的是扩展欧几里德,不过看讨论版,简单的一次方程加上位操作也可以解决,不过因为各种细节问题wa的并不在少数
题解用long long只是以防万一,这类题目数字往往很大,尤其这个题没有给出常数的限制,开大些也不会太影响效率
1.注意输入限制,只有四个数都是0才算输入结束,也就是说有一个不是0就可以继续处理,同样,c==0并非一定是FOREVER,因为a和b有可能相等,为0次,这点在样例输入中有体现
题解状态:
208K,16MS,C++,984B
#include<cmath>
#include<cctype>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<numeric>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<list>
#include<stack>
using namespace std;
long long exgcd(long long a, long long b, long long &x, long long &y)
{
if (!b) {
x = 1;
y = 0;
return a;
}
long long ans = exgcd(b, a%b, x, y);
long long t = x;
x = y;
y = t - a / b*y;
return ans;
}
long long fun(long long a, long long b, long long c, long long k)
{
long long x, y;
long long d = (long long)(pow(2.0, (double)k));
long long ans = exgcd(c, d, x, y);
if ((b - a) % ans != 0)
return -1;
else {
x *= (b - a) / ans;
d /= ans;
x = (x%d + d) % d;
return x;//这几行似乎已经成为扩展欧几里德题的必备套路,除了算乘方那一行
}
}
int main(void)
{
//freopen("vs_cin.txt", "r", stdin);
long long a, b, c, k, ans;
while (~scanf("%lld%lld%lld%lld", &a, &b, &c, &k) && (a || b || c || k)) {//input//参见讨论1
ans = fun(a, b, c, k);
if (ans != -1)
printf("%lld\n", ans);//output
else
printf("FOREVER\n");//output
}
}
EOF