开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情
题目
对于 C 语言的循环语句,形如:
for (variable = A; variable != B; variable += C)
statement;
请问在 k� 位存储系统中循环几次才会结束。
若在有限次内结束,则输出循环次数。否则输出死循环。
输入格式
多组数据,每组数据一行四个整数 A,B,C,k�,�,�,�。
读入以 0 0 0 0 结束。
输出格式
若在有限次内结束,则输出循环次数。
否则输出 FOREVER。
数据范围
1≤k≤321≤�≤32,
0≤A,B,C<2k0≤�,�,�<2�
输入样例:
3 3 2 16
3 7 2 16
7 3 2 16
3 4 2 16
0 0 0 0
输出样例:
0
2
32766
FOREVER
分析
这题看似有点难,其实不难,只要了解了扩展欧几里得算法的本质,这题就变得很简单了,首先我们要知道裴蜀定理,裴蜀定理就是说对于任意正整数a和b,一定可以拼出他们的最大公约数gcd,而且gcd是他们所能拼出来的的最小正整数,我们可以用exgcd找到这样一组解,然后再由相应的方式解出通解,那么最下值就是这个x%(k/gcd)。
代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
#include <iomanip>
#include <cmath>
#include <unordered_map>
#include <stack>
#include <queue>
#define ll long long
#define lowbit(x) x&(-x)
using namespace std;
typedef pair<int,int> PII;
typedef pair<string,int> PSI;
ll a,b,c,k;
ll exgcd(ll a,ll b,ll &x,ll &y){//ecgcd过程
if(!b){
x=1,y=0;
return a;
}
ll d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
ll qmi(ll x,ll y,int mod){//快速幂
ll res=1;
while(y){
if(y&1) res=res*x%mod;
y>>=1;
x=x*x%mod;
}
return res;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
while(cin>>a>>b>>c>>k){
if(!a && !b && !c && !k){
break;
}
ll gc=1ll<<k;
ll x,y;
ll d=exgcd(c,gc,x,y);
if((b-a)%d) cout<<"FOREVER"<<"\n";
else{
x*=(b-a)/d;
gc/=d;
cout<<(x%gc+gc)%gc<<"\n";、、防止输出负数
}
}
return 0;
}
希望对大家有所帮助qaq()