Day9:最大公約數(shù)、最小公倍數(shù)(歐幾里得算法),素?cái)?shù)篩法

一、最大公約數(shù)

  • 題目描述

輸入兩個(gè)正整數(shù),求其最大公約數(shù)。

  • 輸入描述

測(cè)試數(shù)據(jù)有多組,每組輸入兩個(gè)正整數(shù)。

  • 輸出描述

對(duì)于每組輸入,請(qǐng)輸出其最大公約數(shù)。

  • 示例輸入

49 14

  • 示例輸出

7

解題思路

a、b的最大公約數(shù)同時(shí)也是b、a mod b的最大公約數(shù)。轉(zhuǎn)化為求b、a mod b的最大公約數(shù),問題不變而數(shù)據(jù)規(guī)模明顯變小。不斷重復(fù)此過程,直到問題縮小成求某個(gè)非0數(shù)與0的最大公約數(shù),則該非0數(shù)即是所求。

歐幾里得算法:
(1)若a、b全為零,則最大公約數(shù)不存在
(2)若a、b其中之一為零,則最大公約數(shù)為非零的那個(gè);
(3)若a、b都不為零,則使新a=b;新b=a%b然后重復(fù)該過程。

代碼9.1

#include <stdio.h>

int gcd(int a, int b){
    if(b == 0) 
        return a;
    else
        return gcd(b, a % b);
}
int main()
{
    int a, b;
    while(scanf("%d%d",&a, &b) != EOF)
    {
        printf("%d\n",gcd(a, b));
        //若求最小公倍數(shù),a*b/最大公約數(shù) 即可
        //printf("%d\n",a * b / gcd(a, b);
    }
}

二、素?cái)?shù)判定

  • 題目描述

給定一個(gè)數(shù)n,要求判斷其是否為素?cái)?shù)(0,1,負(fù)數(shù)都是非素?cái)?shù))。

  • 輸入描述

測(cè)試數(shù)據(jù)有多組,每組輸入一個(gè)數(shù)n。

  • 輸出描述

對(duì)于每組輸入,若是素?cái)?shù)則輸出yes,否則輸入no。

  • 示例輸入

13

  • 示例輸出

yes

解題思路

素?cái)?shù)即只能被自身和1整除的大于1的正整數(shù),只需要測(cè)試位于區(qū)間[2,sqrt(n))之間的正整數(shù)是否均不能整除n,若均不能整除n,則判定n為素?cái)?shù)。

代碼9.2

#include <stdio.h>
#include <math.h>

bool judge(int n)
{
    if(n <= 1) return false;
    int bound = (int)sqrt(n) + 1; //枚舉上界,為防止double值帶來的精度損失,根號(hào)取整后多+1
    for(int i = 2; i < bound; i++){
        if(n % i == 0) return false;
    }
    return true;
}
int main()
{
    int n;
    while(scanf("%d",&n) != EOF)
    {
        if(judge(n) == true)
            printf("yes\n");
        else
            printf("no\n");
    }    
}

三、素?cái)?shù)篩法

  • 題目描述

輸入一個(gè)整數(shù)n(2<=n<=10000),要求輸出所有從1到這個(gè)整數(shù)之間(不包括1和這個(gè)整數(shù))個(gè)位為1的素?cái)?shù),如果沒有則輸出-1。

  • 輸入描述

輸入有多組數(shù)據(jù)。每組一行,輸入n。

  • 輸出描述

輸出所有從1到這個(gè)整數(shù)之間(不包括1和這個(gè)整數(shù))個(gè)位為1的素?cái)?shù)(素?cái)?shù)之間用空格隔開,最后一個(gè)素?cái)?shù)后面沒有空格),如果沒有則輸出-1。

  • 示例輸入

100

  • 示例輸出

11 31 41 61 71

解題思路

素?cái)?shù)篩法:從2開始遍歷2到10000的所有整數(shù),若當(dāng)前整數(shù)沒有被標(biāo)記成非素?cái)?shù),則判定為素?cái)?shù),并將其所有倍數(shù)標(biāo)記為非素?cái)?shù)。繼續(xù)遍歷下一個(gè)數(shù),直到遍歷完。此時(shí)所有沒被標(biāo)記成非素?cái)?shù)的數(shù)即為篩選出來的素?cái)?shù)。

代碼9.3

#include <stdio.h>

int prime[10000]; //保存篩得的素?cái)?shù)
int primeSize = 0; //保存的素?cái)?shù)個(gè)數(shù)
bool mark[10001]; //mark[x]為true,表示x被標(biāo)記為非素?cái)?shù)
void init() //素?cái)?shù)篩法
{
    for( int i = 1; i <= 10000; i++)//初始化,所有數(shù)字均為被標(biāo)記
    {
        mark[i] = false;
    }
    for(int i = 2; i <= 10000; i++)
    {
        if(mark[i] == true )continue; //若該數(shù)字已被標(biāo)記為非素?cái)?shù),跳過
        prime[primeSize++] = i; //否則為素?cái)?shù)
        for( int j = i*i; j <= 10000; j +=i)//并將該素?cái)?shù)的所有倍數(shù)標(biāo)記為非素?cái)?shù)
        {
            mark[j] = true;
        }
    }
}
int main(){
    init(); //素?cái)?shù)篩法,保存2-10000之間的所有素?cái)?shù)
    int n;
    while(scanf("%d", &n) != EOF)
    {
        bool isOutput = false;
        for(int i = 0; i < primeSize; i++)
        {
            if(prime[i] < n && prime[i] % 10 == 1)
            {
                if(isOutput == false){//第一個(gè)輸出的素?cái)?shù),之前不需要加空格
                    printf("%d", prime[i]);
                    isOutput = true;
                }
                else{
                    printf(" %d",prime[i]);//輸出前加空格
                }
            }
        }
        if(isOutput == false)//不存在符合條件的素?cái)?shù)
        {
            printf("-1\n");
        }
        else printf("\n");
    }
    return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容