POJ 1061 青蛙的约会 (扩展欧几里得)
来源:互联网 发布:淘宝达人在哪里申请 编辑:程序博客网 时间:2024/06/04 17:50
扩展欧几里得算法在理解,第一次学的时候不是很深刻,没做到真正的知行合一(最近比较崇拜王阳明)
扩展欧几里得就是求ax+by=gcd(a,b)的解,而且这个解一定会存在。
b=0,x=1;
a>b>0 时
设 ax1+ by1= gcd(a,b);
bx2+ (a mod b)y2= gcd(b,a mod b);
根据朴素的欧几里德原理有 gcd(a,b) = gcd(b,a mod b);
则:ax1+ by1= bx2+ (a mod b)y2;
即:ax1+ by1= bx2+ (a - [a / b] * b)y2=ay2+ bx2- [a / b] * by2;
也就是ax1+ by1 == ay2+ b(x2- [a / b] *y2);
根据恒等定理得:x1=y2; y1=x2- [a / b] *y2;
如果遇到a*x+b*y=c就朝这方面转化
然后求ax + by = c,判断c如果不能被d整除就Impossible,否则就令x = c/d * x0就可以得到一个x解了。
但有无数个解满足ax + by = c的。为神马呢?ax + by = c其实就等价于ax ≡ c (mod b)对不?如果我得到一个特解x*,
那么加上若干倍b还是这个方程的解,因为a(x*+k*b) = ax* + a*k*b ≡ c + 0 ≡ c (mod b)。因而方程在[0, b-1]上一定有整数解
(假如小于0,你加上若干倍b啊,就可以让它保持在0~b-1中;如果大于b-1,你减去若干倍b啊,它也保持0~b-1)。
最后还要用到扩展欧几里得2个定理,第一次学的时候都没看。。。
1、若gcd(a, b) = 1,则方程ax ≡ c (mod b)在[0, b-1]上有唯一解。
2、若gcd(a, b) = d,则方程ax ≡ c (mod b)在[0, b/d - 1]上有唯一解。
最后一步非负解 用x = (X % r + r) % r就可以求出最小非负整数解x了!(X % r可能是负值,此时保持在[-(r-1), 0]内,
扩展欧几里得就是求ax+by=gcd(a,b)的解,而且这个解一定会存在。
b=0,x=1;
a>b>0 时
设 ax1+ by1= gcd(a,b);
bx2+ (a mod b)y2= gcd(b,a mod b);
根据朴素的欧几里德原理有 gcd(a,b) = gcd(b,a mod b);
则:ax1+ by1= bx2+ (a mod b)y2;
即:ax1+ by1= bx2+ (a - [a / b] * b)y2=ay2+ bx2- [a / b] * by2;
也就是ax1+ by1 == ay2+ b(x2- [a / b] *y2);
根据恒等定理得:x1=y2; y1=x2- [a / b] *y2;
如果遇到a*x+b*y=c就朝这方面转化
然后求ax + by = c,判断c如果不能被d整除就Impossible,否则就令x = c/d * x0就可以得到一个x解了。
但有无数个解满足ax + by = c的。为神马呢?ax + by = c其实就等价于ax ≡ c (mod b)对不?如果我得到一个特解x*,
那么加上若干倍b还是这个方程的解,因为a(x*+k*b) = ax* + a*k*b ≡ c + 0 ≡ c (mod b)。因而方程在[0, b-1]上一定有整数解
(假如小于0,你加上若干倍b啊,就可以让它保持在0~b-1中;如果大于b-1,你减去若干倍b啊,它也保持0~b-1)。
最后还要用到扩展欧几里得2个定理,第一次学的时候都没看。。。
1、若gcd(a, b) = 1,则方程ax ≡ c (mod b)在[0, b-1]上有唯一解。
2、若gcd(a, b) = d,则方程ax ≡ c (mod b)在[0, b/d - 1]上有唯一解。
最后一步非负解 用x = (X % r + r) % r就可以求出最小非负整数解x了!(X % r可能是负值,此时保持在[-(r-1), 0]内,
正值则保持在[0, r-1]内。加上r就保持在[1, 2r - 1]内,所以再模一下r就在[0, r-1]内了)。
#include <iostream>using namespace std;long long ex_gcd(long long a,long long b,long long &x,long long &y){ long long d,t; if(b==0) { x=1; y=0; return a; } d=ex_gcd(b,a%b,x,y); t = x - a / b * y; x = y; y = t; return d;}int main(){ long long x,y,m,n,L,d,r,x1,y1; while(cin>>x>>y>>m>>n>>L) { d=ex_gcd(n-m,L,x1,y1); r=L/d; if((x-y)%d)cout<<"Impossible"<<endl; else cout<<((x - y) / d*x1%r+r)%r<<endl;//然后求ax + by = c,判断c如果不能被d整除就Impossible,否则就令x = c/d * x0就可以得到一个x解了。 } return 0;}
我也试过其他方法,会超时,和扩展欧几里得一个思路,
小学生水平,所以超时了
int main(){ long long x, y, m, n, L; while (cin >> x >> y >> m >> n >> L) { long long a=0,b=0;//a是当前的快的需要超越的圈数,b是快的比慢的快的速度 if(m==n)cout<<"Impossible"<<endl; else if(m>n&&x>y)a=L-(x-y),b=m-n; else if(m>n&&x<y)a=x-y,b=m-n; else if(m<n&&x>y)a=y-x,b=n-m; else if(m<n&&x<y)a=L-(y-x),b=n-m; long long t=0; while(a%b!=0) { a=a+L; t+=a/b; a%=b; } t+=a/b; cout<<t<<endl; } return 0;}
0 0
- POJ 1061 青蛙的约会 扩展欧几里得
- poj 1061 青蛙的约会 扩展欧几里得
- poj 1061青蛙的约会(扩展欧几里得)
- POJ 1061 青蛙的约会( 扩展欧几里得)
- poj 1061 青蛙的约会(扩展欧几里得)
- Poj 1061 青蛙的约会(扩展欧几里得)
- POJ-1061-青蛙的约会(扩展欧几里得)
- poj 1061 青蛙的约会 【扩展欧几里得】
- poj 1061 青蛙的约会(扩展欧几里得)
- POJ 1061 青蛙的约会 扩展欧几里得
- POJ 1061 青蛙的约会 (扩展欧几里得)
- poj 1061 青蛙的约会 【扩展欧几里得】
- POJ 1061 青蛙的约会(扩展欧几里得)
- POJ 1061 青蛙的约会(扩展欧几里得)
- poj 1061 青蛙的约会 【扩展欧几里得】
- Poj 1061 青蛙的约会(扩展欧几里得)
- poj 1061 青蛙的约会 扩展欧几里得
- poj-1061-青蛙的约会【扩展欧几里得】
- Java学习笔记1
- 廖雪峰Python教程 学习笔记3 hello.py
- InputField 限制字数
- qt中listwidgetitem注意事项
- UE4渲染任务的产生及入队
- POJ 1061 青蛙的约会 (扩展欧几里得)
- 【专题训练】医院设置[2] | 树的边、点都带权重心
- .net core学习资料整理
- [普及] NOIP 2012 摆花
- LeetCode 413 Arithmetic Slices (找等差数列)
- 取整
- hdu 5952 Counting Cliques 暴力枚举+优化
- Zookeeper 与 Kafka (1) : 分布式一致性原理与实践
- ListView的渐变。。淡入和淡出 第一个Item和最后一个Item