POJ 2115 C Looooops

来源:互联网 发布:java正则验证端口号 编辑:程序博客网 时间:2024/05/16 15:19

这题只要知道知识点就能过,不知道就过不了……

题目大意:
给出一个for循环语句,for(i=A ; i!=B ;i +=C),问循环几次能结束。

这个是建立在变量是无符号k位的,即变量的数值在0到2的k次方之间,当超过2的k此方时,会溢出,也就是对2的k次方取余只有这样才有可能在有限次循环下结束。


解题思路:
通过这个for循环可以看出本题是求B-A+(2^k)*y=C*x求x的问题。

只要X有确定解就输出,无解就输出FOREVER。

然后就转换成了C*x=(B-A)mod(2^k);

求出最小的正整数x。


下面是代码:

#include <iostream>using namespace std;long long  ext_gcd(long long  a, long long b,long long &x,long long &y){    if(b==0)    {        x=1;        y=0;        return a;    }    long long d=ext_gcd(b,a%b,x,y);    long long t=x;    x=y;    y=t-a/b*y;  //系数x、y的取值是为满足等式d=ax+by    return d;}int main(){    long long a,b,c,k,d,n,x,y;    while(cin>>a>>b>>c>>k)    {        if(!a&&!b&&!c&&!k)        {            break;        }        n=1ll<<k;        d=ext_gcd(c,n,x,y);        if((b-a)%d)        {            cout <<"FOREVER"<<endl;        }        else        {            x=(x*(b-a)/d)%n;            x=(x%(n/d)+n/d)%(n/d);            cout <<x<<endl;        }    }    return 0;}




0 0