1. 程式人生 > >演算法學習1 求兩個數的最大公因數 例,求a和b^b的最大公因數

演算法學習1 求兩個數的最大公因數 例,求a和b^b的最大公因數

最大公因(約)數,是指兩個或多個整數共有因數中最大的一個。兩個數a,b的最大公因數記作(a,b)。

求最大公因數的演算法有:

(1)輾轉相除法
有兩整數a和b:
    ① a%b得餘數c
    ② 若c=0,則b即為兩數的最大公約數
    ③ 若c≠0,則a=b,b=c,再回去執行①
例如求27和15的最大公約數過程為:
    27÷15 餘12 15÷12餘3 12÷3餘0。因此,3即為最大公約數

⑵ 更相減損法
有兩整數a和b:
    ① 若a>b,則a=a-b
    ② 若a<b,則b=b-a
    ③ 若a=b,則a(或b)即為兩數的最大公約數
    ④ 若a≠b,則再回去執行①
例如求27和15的最大公約數過程為:
    27-15=12( 15>12 ) 15-12=3( 12>3 )
    12-3=9( 9>3 ) 9-3=6( 6>3 )
    6-3=3( 3==3 )
    因此,3即為最大公約數
    
⑶窮舉法
有兩整數a和b:
    ① i=1
    ② 若a,b能同時被i整除,則t=i
    ③ i++
    ④ 若 i <= a(或b),則再回去執行②
    ⑤ 若 i > a(或b),則t即為最大公約數,結束
改進:
    ① i= a(或b)
    ② 若a,b能同時被i整除,則i即為最大公約數,
    結束
    ③ i--,再回去執行②

下面以一個實際例子來解釋第一種演算法。

【例1】實際問題,求a和b^b次方的最大公因數。

描述

    As we know, gcd(A, B) means the Greatest Common Divisor (GCD) of A and B.

    But zy thinks it is so easy to just let you calculate it.
    So now your task is to calculate gcd(A, B^B),it is easy right?

    Notice: B ^ B means B multiply by himself B times.

輸入

    Multiply test case, each case per line.
    Each line 2 integers A, B, 1 <= A, B <= 1000

輸出

    For each test case output one line( one number ), indicating the value of gcd (A, B^B)

樣例輸入
100 1
100 2
樣例輸出1
1
4

解決方案分析:

    !!!注意!!!
    這裡有個大坑!!!
    這裡是求a與b^b次方的最大公因數,想當然的肯定是先求出b^b的值,再求a與b^b的最大公因數。
    !!!但是!!!
    當b取值很大時,b^b的值會非常之大!!!而且pow函式的返回的可表示最大數的數值型別為long double(12位元組),當求冪的數過大時,pow無法給出正確計算結果。

    因此,這裡採取一個比較巧妙的方法:

    記a與b的最大公因數為(a,b),可知a與b^b的最大公因數(a,b^b)。

演算法如下:

  1. 求出(a,b),並使用result = result * (a,b)儲存連乘的結果。轉到2。
  2. 如果(a,b) == 1,結束。(a,b^b) = result。
  3. 如果(a,b) != 1,令a = a/(a,b),轉到1。
具體程式碼如下:
#include<iostream>
using namespace std;

int gcd(int a, int b){
    int r;
    while(b!=0){
        r = a % b;
        a = b;
        b = r;
    }
    return a;
}

int main(){
    int a,b,result,flag;
    while(cin >> a >> b){
        result = 1;
        if(a<1 || b>1000)
            exit(0);
        for(int i=0; i<b; i++){
            flag = gcd(a,b);
            result = result*flag;
            if(flag == 1)
                break;
            else
                a = a/flag;
        }    
        cout << result << endl;
    }
    return 0;
}

也可以寫成如下的簡潔形式:

#include<iostream>
using namespace std;

int gcd(int a, int b){
    int r;
    while(b!=0){
        r = a % b;
        a = b;
        b = r;
    }
    return a;
}

int main(){
    int a,b,result,flag;
    while(cin >> a >> b){
        result = 1;
        if(a<1 || b>1000)
            exit(0);
         for(; gcd(a,b)!=1; a=a/gcd(a,b)){
                result = result*gcd(a,b);
        }
        cout << result << endl;
    }
    return 0;
}


相關推薦

演算法學習1 個數大公因數 ab^b大公因數

最大公因(約)數,是指兩個或多個整數共有因數中最大的一個。兩個數a,b的最大公因數記作(a,b)。求最大公因數的演算法有:(1)輾轉相除法有兩整數a和b:    ① a%b得餘數c    ② 若c=0,則b即為兩數的最大公約數    ③ 若c≠0,則a=b,b=c,再回去執行

不允許用(a+b)/2這種方式個數的均值;如下程序在Linux32位集成開發環境中運行

left 定義 inf log post efi mage 技術 def #define MAX(a,b) ((a)>(b)?(a):(b)) #include<stdio.h> int main() { int a = 10; int

輸入三個數a,b,n輸出ab不大於n的公倍數的個數

name () 招商 int col 輸入 pac clas div 題:輸入三個數a,b,n,輸出a和b不大於n的公倍數的所有個數。 這題的思想是先求得a和b的最大公約數,然後用a和b的積除以最大公約數,得到最小公倍數,再持續加上最小公倍數,直到超過n,記下n的個數。如:

c語言經典題演算法1--用輾轉相除法個數大公約數

題目: 用輾轉相除法求兩個數的最大公約數 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.

1.交換值內容 2.不創建臨時變量交換只內容 3.個數中的大值 4.講三個數由大到小輸出 5.個數大公約數

www. 最大公約數 十個 following .com blank 臨時變量 lan follow 露x都對貝姨芽沽1才39賢http://www.facebolw.com/space/2104128 ZP鋪巢嗣3瀉HX7Dhttp://www.facebolw.com

你所必須知道的三種基本個數大公約數的演算法

1 迭代法求最大公約數 /*迭代法求最大公約數 *原理:m n r;將r賦值給n,n賦值給m */ #include <iostream> using namespace std; int Gcd(int m, int n) { int r; r =

演算法個數大公約數與小公倍數的方法

1、計算兩個整數的最大公約數方法有兩種 第一種是使用《九章算術》中的更相減損術方法,“以少減多,更相減損,求其等也,以等數約之,等數約之,即除也,其所以相減者皆等數之重疊,故以等數約之。”其大概意思就是“若分子、分母均為偶數時,可先被2除,否則,將分子與分母之數列在它處,然後以小數減大數,輾

個數大公約數

pri div temp 輾轉相除法 公約數 歐幾裏德算法 最大 ebo != #-*-coding:utf-8-*- ‘‘‘ 求兩個數的最大公約數 算法參考:https://zhidao.baidu.com/question/36550887.html by:rebor

個數大公約數小公倍數

兩個 rem pac [] while ext bre list AS package java; import java.util.ArrayList; import java.util.List; import java.util.Scanner; pu

個數大公約數小公倍數

esp long cout gcd urn clas 代碼 () else 求最大公約數利用輾轉相除法: long long gcd(long long a,long long b) { if(b==0) return a; else

個數大公約數輾轉相除法與更相減損法(遞歸叠代)

叠代 div 余數 公約數 穩定 log test 算法 復雜度 問題:給出兩個數a和b,求出他們的最大公約數(greatest common divisor)。 解法一:輾轉相除法,又叫歐幾裏得算法。兩個正整數a和b(a>b),他們的最大公約數等於a除以b的余數和b

個數大公約數小公倍數

題目描述 輸入兩個正整數m和n,求其最大公約數和最小公倍數。 輸入 兩個整數 輸出 最大公約數,最小公倍數 解題思路 最大公約數(GCD)和最小公倍數(LCM)的計算方法可以在這裡獲取[這兒] 本文先用輾轉相除法求出

個數大公約數

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include<stdlib.h> void main() { int a,b,i; printf("請輸入2個整數\n"); scanf("%d%d", &

c++中個數大公約數小公倍數(輾轉相除法)

輸入兩個正整數m和n,求其最大公約數和最小公倍數 #include "stdafx.h" #include<iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) {

作業2.3:個數大公約數小公倍數?

#include<stdio.h> #include<math.h> int fun_y(int,int); int fun_b(int,int); main() { int a,b,gy,gb; printf("輸入兩個整數:\n");

個數大公約數。

#define _CRT_SECURE_NO_WARNINGS #include "stdio.h" #include "stdlib.h" int main() { int a = 0, b =

C語言個數大公約數小公倍數

輾轉相除法, 又名歐幾里德演算法(Euclidean algorithm),是求最大公約數的一種方法。它的具體做法是:用較小數除較大數,再用出現的餘數(第一餘數)去除除數,再用出現的餘數(第二餘數)去除第一餘數,如此反覆,直到最後餘數是0為止。如果是求兩個數的最

【經典100題】 題目16 個數大公約數小公倍數

題目 求兩個數的最大公約數和最小公倍數。 最大公約數:指兩個或多個整數共有約數中最大的一個 最小公倍數:指兩個或多個整數共有倍數中最小的一個 說明:自己沒有搞清楚最大公約數和最小公倍數的定義,結果走了不少彎路,下面的解法是一種比較簡單但是效率的不高的解法。可以參考“輾除法”,在後續會

C#基礎:個數大公約數小公倍數

            int number1 = 0;             int  number2 = 0;             Console.WriteLine("請輸入兩個整數:");             number1 = int.Parse(Console.ReadLine()

輾轉相除法個數大公約數

輾轉法相除:先將大數除以小數,如果整除,小數就是它們的最大公因數,如果不能整除,就記下餘數,用前面的除數(就是小數),除以這個餘數,以下類推,每一次都用前一個除式的除數除以自己的餘數,直到有一個除法能整除,這時,最後能整除的除式的除數,就是這兩個數的最大公因數。   #define