poj2115
大致题意:
对于C的for(i=A ; i!=B ;i +=C)循环语句,问在k位存储系统中循环几次才会结束。
若在有限次内结束,则输出循环次数。
否则输出死循环。
解题思路:
根据题意可得方程:
A+C*X=B (X 再%2^k 就是最后要的结果。)
X=[(B-A) / C]% 2^k
=[(B-A) % 2^k] / C (C 不需要%,因为
(0 <= A, B, C < 2k) )
=[(B-A)+2^k]%2^k /C
CX=[(B-A)+2^k]%2^k (说明 (B-A)与CX 关于 2^k 同余)
所以 CX - (B-A) 是 2^k 的整数倍 PS:因为两个%它 余数相同的话,,两个相减就把余数减掉了!
所以得到方程:
C*X+Y*2^k=(B-A) PS:(Y是倍数,X即为所求)
解法就很清晰了!
先用 exgcd 求出一组解,然后再模一下 求出 最小解就ok了!
FOREVER 的情况就是(B-A)%gcd 不是整数的情况。。即无限循环!!
//Accepted 132K 0MS C++ 646B
#include
#include
using namespace std;
typedef long long ll;
void exgcd(ll a,ll b,ll& d,ll& x,ll& y)
{
if(!b){d=a;x=1;y=0;}
else{exgcd(b,a%b,d,y,x);y-=x*(a/b);}
}
ll mod(ll a,ll b,ll n)
{
ll d,x,y,l;
exgcd(a,n,d,x,y);
if(b%d!=0) return -1;
x*=b/d;
l=n/d;
x=(x%l+l)%l;
return x;
}
int main()
{
ll A,B,C,k;
while(~scanf("%I64d%I64d%I64d%I64d",&A,&B,&C,&k))
{
if(A==0&&B==0&&C==0&&k==0) break;
ll flag;
flag=mod(C,B-A,1LL<