辗转相除法——求最大公约数

一、题目描述

    在一个由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;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值