POJ
来源:互联网 发布:银行卡四件套淘宝网 编辑:程序博客网 时间:2024/05/17 04:51
首先要知道扩展欧几里得,说白了就是解二元一次方乘,二元一次的话肯定有多解,看题目要求求出最优解。
设一共跳了t次
(x + m*t) % l = (y + n*t)
可以化简为:
(m - n)*t % l = y - x
设取余的时候去掉了k个l,那么可以化简为:
(m - n)*t + l*k = y - x
显然这是一个方乘
然后套用扩展欧几里得
int extgcd(int a, int b, int &x, int &y) { if(!b) { x = 1; y = 0; return a; }else { int r = extgcd(b, a%b, y, x); y -= x * (a / b); return r; }}
上面的代码并没有用到ax+by=c中的c,因为我们计算出的是与答案的最小公倍数
举一个例子
6x + 15y = 9 return 的值是 3 ,
6*(-2) + 15*1=3,两边同时乘以3,
6*(-6) + 15*3 = 9,x=-6,y=3,就是一组解;
所以我们首先判断return的数字是不是可以被c整除,不能的话就是无解
令gcd = extgcd(a,b,x,y),c=y-x;
t = (t * cgcd ) % lgcd
最后一步的解释
设要解的方程(求x)是:
ax1 + by1 = c
而我们已经解得
ax + by = gcd(a,b) = d
此时将第二个方程左右同时乘c/d,则可得:
ax∗cd +by∗cd =c
所以:
x1 =x ∗ cd
这样并没有完,因为这只是一组解,我们要求最小正整数解。
我们知道:若一组 < x,y > 是ax+by=c的一组解,那么
< x−
也是原方程的一组解。
这样我们只需要让解得的x不断减b/d,直到再减就为负数时,所得的x就是我们要的解。
#include<iostream>#define ll long longusing namespace std;ll extgcd(ll a, ll b, ll &x, ll &y) { if(!b) { x = 1; y = 0; return a; }else { ll r = extgcd(b, a%b, y, x); y -= x * (a / b); return r; }}int main() { ll x, y, m, n, l; while(cin >> x >> y >> m >> n >> l) { if(m == n) puts("Impossible"); else { if(m < n) swap(m, n), swap(x, y); ll a = m - n; ll c = y - x; ll gcd = extgcd(a, l, x, y); if(c % gcd) { puts("Impossible"); }else { printf("%lld\n", ((x*c/gcd)%(l/gcd)+(l/gcd))%(l/gcd));//展开取余,怕超范围 } } } return 0;}
阅读全文
0 0
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- HTML 逆序输出 输出引号
- 文章标题
- 顺序表的基本操作
- Docker 镜像的存储机制
- SonarQube插件开发自定义规则(1)简易demo
- POJ
- Java之多线程Runnable(2)卖烤鸭-yellowcong
- 566. Reshape the Matrix Difficult : Easy
- css之transform篇
- 【LibUIDK界面库系列文章】响应默认按钮
- 用顺序表实现俩有序顺序表拼接后还是有序的
- 九月总结:快速成长的一个月
- DateConverter does not support default String to 'Date' conversion
- C/C++程序的内存空间及堆、栈区比较