1. 程式人生 > >輾轉相除法——求最大公約數

輾轉相除法——求最大公約數

一、題目描述

    在一個由1×1的格子組成的平面上,給出兩個格子的交點P1(x1,y1)和P2(x2,y2).要求計算出線段P1P2上還有多少格子交點。

        

二、樣例

    輸入:P1=(1,11),P2=(5,3)

    輸出:3{(2,9),(3,7),(4,5)}

三、解題思路

    先將線段當作向量P1P2將P1移到座標原點,向量為P1P2={(x2-x1),(y2-y1)},令a=y2-y1,b=x2-x1,c為a和b的最大公約數即c=gcd(a,b),則P1P2={b,a},其斜率為:K=a/b=(a/c)/(b/c),若令a1=a/c,b1=b/c,則a1與b1互質且K=a1/b1.令Qt={t×b1,t×a1} t={1,2,3,4......,c},則Qt是在向量P1P2

上的且其也是交點,當t=c時Qt就是P2,所以交點數為c-1即gcd(a,b).

四、輾轉相除法

    輾轉相除法是用來求兩個數的最大公約數.

    其主要思想: 假設a>b,令a=b×p+q,假設c為a,b的最大公約數即c=gcd(a,b).則有a和b都能整除c.而a=b×p+q,立即推出q也能整除c,故q與b的公約數,但是不是最大公約數呢。這裡我們用反證法,假設q與b的最大公約數為c1且c1>c,即gcd(b,q)=c1>c,所以b和q都能整除c1,立即推出a也一定能整除c1,故a與b最大公約數應該大於等於c1,即gcd(a,b)=c>=c1,與c1>c矛盾。故c1=c,

    所以得出結論:gcd(a,b)=gcd(b,a%b)且當b=0時有gcd(a,b)=a.

五、最大公約數程式碼

#include <iostream>
#include <stdio.h>
using namespace std;

int gcd(int a,int b)//求a,b最大公約數
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}

int main()
{
    int a,b,c;
    scanf("%d,%d",&a,&b);
    if(a<=b)//大的放前
        c=gcd(a,b);
    else
        c=gcd(b,a);
    printf("%d\n",c);
    return 0;
}

六、該題的程式碼


#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;

int gcd(int a,int b)//求a,b最大公約數
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}

int main()
{
    int a,b,c;
    int x1,x2,y1,y2;
    scanf("%d%d",&x1,&y1);//輸入的一個點
    scanf("%d%d",&x2,&y2);//輸入的二個點
    a=abs(x2-x1);
    b=abs(y2-y1);
    if(a<=b)//大的放前
        c=gcd(a,b);
    else
        c=gcd(b,a);
    printf("%d\n",c-1);
    return 0;
}