• ACM_扩展欧几里德算法


    <pre name="code" class="cpp">/*
    	扩展欧几里德算法
    
    基本算法:对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by。
    
    证明:设 a>b。
    
      1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;
    
      2,ab!=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;
    
      根据恒等定理得:x1=y2; y1=x2-(a/b)*y2;
    
         这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
    
       上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。
    */
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    int exgcd(int a, int b, int &x, int &y) {
    	if (b == 0) {
    		x = 1; 
    		y = 0;
    		return a;
    	}
    	int r = exgcd(b, a%b, x, y);
    	int t = x;
    	x = y;
    	y = t - (a/b) * y;
    	return r;
    }
    
    int main() {
    	int a, b, x, y;
    	while (cin >> a>> b) {
    		int r = exgcd(a, b, x, y);
    		cout << "最大公约数为"<< r<< "   "<< "x、y的值分别为" << x << "	"<< y<< endl; 
    		cout << "方程的每一个解都可以由 "<< x <<"+ k*"<< b/r<< "	"<< y << "- k*"<< a/r<< " 得到!"<< endl<< endl; 
    	}	
    	return 0;
    }
    


    
    
    
       
    
    
  • 相关阅读:
    c语言中srand和rand函数 生成随机数总结
    枚举类型
    VS2008快捷键使用技巧
    PV实现同步
    PV操作(深入显出)
    数字在排序数组中出现的次数
    两个链表的第一个公共结点
    数组中的逆序对
    第一个只出现一次的字符位置
    丑数
  • 原文地址:https://www.cnblogs.com/Tovi/p/6194833.html
Copyright © 2020-2023  润新知