zoukankan      html  css  js  c++  java
  • 扩展欧几里得

    扩展欧几里得算法:对方程 ax + by = gcd(a, b) ,该算法可以找出这个方程的一对整数解 (x, y) ,这里的 x 和 y 不一定是正数,也可能是负数或零。算法代码如下:

    1 //d就是gcd(a,b), (x,y)就是式子 ax+by=gcd(a,b) 的一个解
    2 void exgcd(int a, int b, int& d, int& x, int& y){
    3     if(!b) { d = a; x = 1; y = 0; }
    4     else { exgcd(b, a%b, d, y, x); y -= x*(a/b); }
    5 }

    上面的代码仅仅是可以求出方程的一组解,我们还得求出其他解,我们可以经过推导可以得出这个方程的通解为 (x+kn, y-km) ,这里的k为任意整数,n=b/gcd(a,b),m=a/gcd(a,b) 。这就是我们这个方程的通解的表达式。

    由以上结论,我们可以推导下一个结论:一个方程 ax + by = c 中,令 g=gcd(a,b), 若 c 是 g 的倍数,则该方程的一组解就是 (x*c/g, y*c/g),若 c 不是 g 的倍数,则该方程无整数解。

    有了以上结论,我们就可以试试下面这题了:

    https://vjudge.net/problem/OpenJ_Bailian-1061

    我们假设青蛙跳了 t 次才能碰面,则我们可以列出式子:(x+m*t)%L = (y+n*t)%L , 我们将其变型一下:x-y = t*(n-m) + k*L ,我们可以通过扩欧算法求出 t 和 k 的一个整数解。具体代码如下:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 
     5 void exgcd(LL a, LL b, LL& d, LL& x, LL& y){
     6     if(!b) { d = a; x = 1; y = 0; }
     7     else { exgcd(b, a%b, d, y, x); y -= x*(a/b); }
     8 }
     9 
    10 int main(){
    11     LL a, b, d, x, y, t, m, n, L;
    12     cin >> a >> b >> m >> n >> L;
    13     t = a - b;
    14     exgcd(n-m, L, d, x, y);
    15     if(t%d != 0) {
    16         cout << "Impossible" << endl;
    17     }else {
    18         x = t / d * x;
    19         x = (x % L + L) % L;
    20         cout << x << endl;
    21     }
    22     return 0;
    23 }
    View Code
  • 相关阅读:
    【leetcode】Climbing Stairs (easy)
    【leetcode】Best Time to Buy and Sell 3 (hard) 自己做出来了 但别人的更好
    【leetcode】Best Time to Buy and Sell 2(too easy)
    【leetcode】Best Time to Buy and Sell (easy)
    【leetcode】Single Number II (medium) ★ 自己没做出来....
    【leetcode】Single Number (Medium) ☆
    【leetcode】Valid Sudoku (easy)
    【leetcode】Two Sum (easy)
    Oracle-11-主键约束
    Codeforces444A_DZY Loves Physics
  • 原文地址:https://www.cnblogs.com/DynastySun/p/9364142.html
Copyright © 2011-2022 走看看