poj2115-C Looooops(扩展欧几里德算法)

本题和poj1061青蛙问题同属一类,都运用到扩展欧几里德算法,可以参考poj1061,解题思路步骤基本都一样。
一,题意:
  对于for(i=A ; i!=B ;i+=C)循环语句,问在k位存储系统中循环几次才会结束。
    比如:当k=4时,存储的数 i 在0-15之间循环。(本题默认为无符号)
  若在有限次内结束,则输出循环次数。
  否则输出死循环。
二,思路:
本题利用扩展欧几里德算法求线性同余方程,设循环次数为 x ,则解方程 (A + C*x) % 2^k = B ;求出最小正整数 x。
  1,化简方程化为求线性同余方程标准式 ax = b (mod n);
  2,扩展欧几里德算法求解线性同余方程 C*x = B-A (mod 2^k);
  3,求出最小非负整数解。
三,步骤:
  1,化简:(A + C*x) mod 2^K = B  -->  C*x mod 2^k = B-A  -->   C*x = B-A (mod 2^k);
  2,求线性同余方程 C*x = B-A (mod 2^k) , 就相当于求二元一次方程 C*x + 2^k * y = B-A
    i,代入扩展欧几里德算法,求解方程 C*x + 2^k * y = gcd(C , 2^k) ;
    ii,利用方程 C*x + 2^k * y = gcd(C , 2^k)的解 x0 以及公式 x1 = x0 * c/d 求出原方程 a*x + b*y = c 的解 x1 ;前提是:d|c (c 能被 d 整除);
   3,利用周期性变化求最小的非负整数解 公式: x1 = (x1 % (b/d) + (b/d) ) % (b/d);

    若方程的C*x + 2^k * y = B-A 的一组整数解为(x1 , y1),则它的任意整数解为(x1 + k * (b/d) , y1 - k * (a/d) ) ( k取任意整数 ), T = b/d就为 x1 增长的周期

     i,若x1为负值,取最大的非正值:x1 = x1 % T ; 若x1为正值,以下两步无影响;
     ii,取正 :x1 = x1 + T ;
     iii, 防止 i 中的 x1=0 即 ii 中的 x1=T :x1 = x1 % T ;

代码如下:

 1 #include<iostream>
 2 using namespace std;
 3
 4 void exgcd(long long a,long long b,long long& d,long long& x,long long& y){//int& a 是定义一个存放整形变量a的地址
 5     if(!b){ d=a ; x=1 ; y=0; }              // d用来存储gcd(a,b)的值
 6     else { exgcd(b , a%b , d , y , x); y -= x* (a/b); }
 7 }
 8
 9 int main(){
10     long long  A,B,C,d,x,y,T;
11     int k ;
12     while(cin>>A>>B>>C>>k){
13         if(A==0&&B==0&&C==0&&k==0)
14              break;
15         long long n = 1LL<<k; //n = 1 * 2^k ;注意此处,若为__int64,则应该是n = (__int64)1 << k;
16         exgcd(C,n,d,x,y);
17         if( (B-A) % d != 0 ){
18             cout<<"FOREVER\n";
19         }
20         else {
21             x = x * (B-A) / d ;
22             T = n / d;
23             x = ( x%T + T ) % T ;
24             cout<<x<<endl;
25         }
26     }
27     return 0;
28 } 

 如发现错误或者有不理解的地方,请联系我。

时间: 2024-11-07 07:55:54

poj2115-C Looooops(扩展欧几里德算法)的相关文章

POJ2115 C Looooops 扩展欧几里德

欢迎访问~原文出处--博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ2115 题意 对于C的for(i=A ; i!=B ;i +=C)循环语句,问在k位存储系统中循环几次才会结束.若在有限次内结束,则输出循环次数.否则输出死循环. 题解 原题题意再次缩略: A + xC Ξ B (mod 2k) 求x的最小正整数值. 我们把式子稍微变一下形: Cx + (2k)y = B-A 然后就变成了一个基础的二元一次方程求解,扩展欧几里德套套就可以了. 至于扩展欧几里德(ex

POJ2115——C Looooops(扩展欧几里德+求解模线性方程)

C Looooops DescriptionA Compiler Mystery: We are given a C-language style for loop of type for (variable = A; variable != B; variable += C) statement;I.e., a loop which starts by setting variable to value A and while variable is not equal to B, repea

poj2142-The Balance(扩展欧几里德算法)

一,题意: 有两个类型的砝码,质量分别为a,b;现在要求称出质量为d的物品, 要用多少a砝码(x)和多少b砝码(y),使得(x+y)最小.(注意:砝码位置有左右之分). 二,思路: 1,砝码有左右位置之分,应对比两种情况 i,a左b右,得出方程 ax1 - by1 = d ; ii,b左a右,得出方程 bx2 - ay2 = d . 2,利用扩展欧几里德算法,解出(x1,y1).(x2,y2),并求出最小x1和x2,以及相对应的y1,y2. 3,输出x1+y1和x2+y2 中的最小值. 三,步骤

扩展欧几里德算法

文章来源:http://blog.csdn.net/zhjchengfeng5/article/details/7786595 谁是欧几里德?自己百度去 先介绍什么叫做欧几里德算法 有两个数 a b,现在,我们要求 a b 的最大公约数,怎么求?枚举他们的因子?不现实,当 a b 很大的时候,枚举显得那么的na?ve ,那怎么做? 欧几里德有个十分又用的定理: gcd(a, b) = gcd(b , a%b) ,这样,我们就可以在几乎是 log 的时间复杂度里求解出来 a 和 b 的最大公约数了

欧几里德与扩展欧几里德算法(转)

欧几里德算法 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b). 第一种证明: a可以表示成a = kb + r,则r = a mod b 假设d是a,b的一个公约数,则有 d|a, d|b,而r = a - kb,因此d|r 因此d是(b,a mod b)的公约数 假设d 是(b,a mod b)的公约数,则 d | b , d |r ,但是a

HDU 1098 Ignatius&#39;s puzzle 费马小定理+扩展欧几里德算法

题目大意: 给定k,找到一个满足的a使任意的x都满足 f(x)=5*x^13+13*x^5+k*a*x 被65整除 推证: f(x) = (5*x^12 + 13 * x^4 + ak) * x 因为x可以任意取 那么不能总是满足 65|x 那么必须是 65 | (5*x^12 + 13 * x^4 + ak) 那么就是说 x^12 / 13 + x^4 / 5 + ak / 65 正好是一个整数 假设能找到满足的a , 那么将 ak / 65 分进x^12 / 13 + x^4 / 5中得到

欧几里德与扩展欧几里德算法

转自网上大牛博客,讲的浅显易懂. 原文地址:http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html 欧几里德算法 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b). 第一种证明: a可以表示成a = kb + r,则r = a mod b 假设d是a,b的一个公约数,则有

扩展欧几里德算法及其证明

扩展欧几里德算法: 已知a, b求解一组x,y,使它们满足等式: ax+by = gcd(a, b) =d(解一定存在,根据数论中的相关定理). 扩展欧几里德常用在求解模线性方程及方程组中. 证明: ax+by=gcd(a,b); 1. (1) a = 0,ax+by = gcd(a,b) = gcd(0,b) = b, 此时x = 0(此时x的值是任意的),y = 1: (2)b = 0, ax + by = gcd(a,b) = gcd(a,0) = a, 此时x = 1,y = 0(此时y

(扩展欧几里德算法)zzuoj 10402: C.机器人

10402: C.机器人 Description Dr. Kong 设计的机器人卡尔非常活泼,既能原地蹦,又能跳远.由于受软硬件设计所限,机器人卡尔只能定点跳远.若机器人站在(X,Y)位置,它可以原地蹦,但只可以在(X,Y),(X,-Y),(-X,Y),(-X,-Y),(Y,X),(Y,-X),(-Y,X),(-Y,-X)八个点跳来跳去. 现在,Dr. Kong想在机器人卡尔身上设计一个计数器,记录它蹦蹦跳跳的数字变化(S,T),即,路过的位置坐标值之和. 你能帮助Dr. Kong判断机器人能否