[数论]青蛙约会 (扩展欧几里德)

/*  
Name:青蛙约会 (扩展欧几里德) 
  
Actor:HT  
  
Time:2015年7月31日  
  
Error Reporte:  
  
}  
*/ 

#include "stdio.h"
#include "string.h"
#include "iostream"

using namespace std;

int x,y;
//ax+by=gcd(a,b)

int gcd(int a,int b)
{
 if (b==0)
 {
  x = 1;
  y = 0;
  return a;  //b==0时,gcd(a,0)==a,因此x=1,y=0
 }
 int d = gcd(b,a%b); 
 //ax + by =gcd(a,b) = gcd(b,a%b) = b*x0 + a%b*y0 = b*x0 + (a-a/b*b)*y0 = a*y0 + b*(x0-a/b*y0)
 //因此  本层的x 等于上一层的y,本层的y 等于上一层的(x-a/b*y)
 int temp = x;
 x = y;
 y = temp - a/b*y;
 //debug:printf("%d  %d\n",x,y);
 return d;
} //此时的x  y是ax+by=gcd(a,b)的一组特殊解

//扩展欧几里德

//ax + by = gcd(a,b)  ---> (ax + by) * (c/gcd(a,b)) == gcd(a,b) * (c / gcd(a,b)) 
// ---> 新x = x * (c/gcd(a,b))  新y = y * (c/gcd(a,b))   这是ax+by=c的一组特解

//通解:  X = x + (b/gcd) * T
//    Y = y - (a/gcd) * T

int main()
{
 //青蛙约会  x/y    m/n    L
 int pa,pb,m,n,l;
 int a,b,c,ans;
 while(scanf("%d %d %d %d %d",&pa,&pb,&m,&n,&l)!=EOF)
 {
  //( pa + T*m ) - ( pb + T*n ) == l * K
  //(n-m)*T + l*K == pa-pb 注意正负号
  a=n-m;
  b=l;
  c=pa-pb;
  int g = gcd(a,b); //此时求得一组特解,但未必最小
  if(c%g!=0)   //题意可知,X作为次数T,一定是整数,X=x*(c/g),若c/g非整,X非整,则无解
  {
   printf("Impossible\n");
   continue;
  }
  x=x*(c/g);
  y=y*(c/g);
  //当X最小时,由X=x + (b/gcd)*T  当T是使X大于零且最小的值即可
  //那么  令X=0,x = (b/gcd)*T   -----> T=x*gcd/b   
  //※※ps:整型除法--得到的将会是使b/gcd最接近x的T,可能大于可能小于 ,如果大于了,就减去一个b/gcd就好
  int t = x*g/b;
  ans = x - t*b/g;
  if(ans<0) ans+= b/g;
  printf("%d\n",ans);
 }
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值