poj2115(C Looooops)

题目地址:C Looooops

题目大意:

    有一个for循环:for(i=A;A!=B;A+=C)  从A开始每次加上C问至少循环多少次等于B,在K位的储存系统中的特性:

例如int型是16位的,那么int能保存2^16个数据,即最大数为65535(本题默认为无符号),

当循环使得i超过65535时,则i会返回0重新开始计数

如i=65534,当i+=3时,i=1

其实就是 i=(65534+3)%(2^16)=1

  如果循环不到B 则输出死循环。

解题思路:

   扩展欧几里德。

推出解析方程:

设循环x次:

n=2^k。

x=(((B-A)+n)%n) /C

C*x=(B-A)%n

C*x+n*y=B-A

然后看GCD(C,n) 能否被(B-A)整除。则符合扩展欧几里德。

然后通过扩展欧几里德求出X0和Y0 。

所以方程:C*x+n*y=GCD(C,n)的通解为:X0+n/GCD(C,n)*K、Y0-C/GCD(C,n)*K。

举例说明:

例如:
    2x+4y=6
    求出 x0=1、y0=1.
    通解为:1+(4/2)*k 和 1-(2/2)*k。
    因为代入方程k刚好消去。
   之所以除以(2,4)的最大公约数,是因为如果不除会漏掉一些解,例如:漏去3、0

  

所以方程:C*x+n*y=B-A  的通解为  X0*GCD(C,n)+n/GCD(C,n)*K、Y0*GCD(C,n)-C/GCD(C,n)*K。

所以求出最小正整数解X= (X0*GCD(C,n)%(n/GCD(C,n))+n/GCD(C,n))%(n/GCD(C,n))。

代码:

 1 //解析式方程 B-A=C*x+n*y
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <sstream>
 5 #include <cstdlib>
 6 #include <cstring>
 7 #include <cstdio>
 8 #include <string>
 9 #include <bitset>
10 #include <vector>
11 #include <queue>
12 #include <stack>
13 #include <cmath>
14 #include <list>
15 //#include <map>
16 #include <set>
17 using namespace std;
18 /***************************************/
19 #define ll long long
20 #define int64 __int64
21 #define PI 3.1415927
22 /***************************************/
23 const int INF = 0x7f7f7f7f;
24 const double eps = 1e-8;
25 const double PIE=acos(-1.0);
26 const int d1x[]= {0,-1,0,1};
27 const int d1y[]= {-1,0,1,0};
28 const int d2x[]= {0,-1,0,1};
29 const int d2y[]= {1,0,-1,0};
30 const int fx[]= {-1,-1,-1,0,0,1,1,1};
31 const int fy[]= {-1,0,1,-1,1,-1,0,1};
32 const int dirx[]= {-1,1,-2,2,-2,2,-1,1};
33 const int diry[]= {-2,-2,-1,-1,1,1,2,2};
34 /*vector <int>map[N];map[a].push_back(b);int len=map[v].size();*/
35 /***************************************/
36 void openfile()
37 {
38     freopen("data.in","rb",stdin);
39     freopen("data.out","wb",stdout);
40 }
41 priority_queue<int> qi1;
42 priority_queue<int, vector<int>, greater<int> >qi2;
43 /**********************华丽丽的分割线,以上为模板部分*****************/
44 
45 long long exgcd(long long a,long long b,long long &x,long long &y)
46 {
47     if (b==0)
48     {
49         x=1;
50         y=0;
51         return a;
52     }
53     else
54     {
55         long long r=exgcd(b,a%b,x,y);
56         long long t=x;
57         x=y;
58         y=t-a/b*y;
59         return r;
60     }
61 }
62 int main(  )
63 {
64     long long a,b,c,k;
65     while(scanf("%lld%lld%lld%lld",&a,&b,&c,&k)!=EOF)
66     {
67         if (a==0&&b==0&&c==0&&k==0)
68             break;
69         long long z=b-a,p=c;
70         long long q=1LL<<k;
71         long long x,y;
72         long long g=exgcd(p,q,x,y);
73         if (z%g!=0)
74             printf("FOREVER
");
75         else
76         {
77             q=q/g;
78             x*=(z/g);
79             x=(x%q+q)%q;
80             printf("%lld
",x);
81         }
82     }
83     return 0;
84 }
View Code
原文地址:https://www.cnblogs.com/ZhaoPengkinghold/p/3895578.html