POJ 2115 C Looooops

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

题目大意:
给出一个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;
}




posted @ 2013-12-30 13:54  、小呆  阅读(99)  评论(0编辑  收藏  举报