zoukankan      html  css  js  c++  java
  • 线段上格点个数---挑战编程---欧几里得

    线段上格点的个数

    何为格点?

    横纵坐标均为整数的点,可以将坐标面看做一个二维表,线段即两个点为顶点的矩形的对角线,线段由格点组成

    问题:

    给定平面上的两个格点P1(x1,y1)P2(x2,y2),线段上P1P2上,除P1P2以外一共有多少格点

    方法1:

    虽然可以用穷举法,遍历min(x1,x2)xmax(x1,x2)min(y1,y2)ymax(y1,y2)的格点可以得到正确答案,但是复杂度确实O(|x1x2|×|y1y2|)

    方法2:

    其实这个题的答案是|x1x2||y1y2|的最大公约数减去1。(注意,|x1x2|=0|y1y2|=0时,答案为0)

    原因,首先看一下|x1x2||y1y2|的最大公约数代表的是啥? 其实可以看成 在横向和竖向的最大的公共等分数, 比如 6 的等分点可以是 1:1:1:1:1:1分成6份 ,也可以是 2:2:2分成3份,或者是 6,只有1份。(其实对应的是 6能被6,3,1整除) 那么 6和9的最大公共等分数是3,即6分为 2:2:2 , 9分为3:3:3. 那么边长为6和9的矩形,按照这样分会是什么情况呢? 
    这里写图片描述

    通过上图可以看出,大矩形的对角线正好经过 (2,3),(4,6),(6,9) 除开(6,9),就是本体所要求的点。这就是为什么这个题的答案是|x1x2||y1y2|的最大公约数减去1。

    数学:

    那这个题可以转换为求最大公约数的问题,最大公约数一般使用辗转相除法

    辗转相除法的原理: 
    如果有两个自然数a和b(a>b), 可以写成a=k×b+c 
    情况1:如果c=0,那么gcd(a,b)=b 
    情况2:如果c0, 那么gcd(a,b)=gcd(b,c)

    下面提供了3个求最大公约数的方法(顺便一提,a和b的最小公倍数为a×bgcd(a,b)

    #include <iostream>
    #include <cmath>
    using namespace std;
    ///非递归的方法
    int gcd1(int a,int b)
    {
    
        int c;
        do
        {
            c=a%b;
            a=b;
            b=c;
        }while(c!=0);
        return a;
    }
    
    ///递归的方法
    int gcd2(int a,int b)
    {
    
        if(b == 0){
            return a;
        }else{
            return gcd2(b,a%b);
        }
    }
    ///辗转相减法
    int gcd3(int a,int b)
    {
        int c=a-b;
        if(c<0){
            return gcd3(b,a);
        }
        while((a-b)!=0)
        {
            a=a-b;
            if(a<b){
                int tmp=a;
                a=b;
                b=tmp;
            }
        }
        return a;
    }
    
    int main(void)
    {
        int x1,x2,y1,y2;
        cout<<"input x1,y1,x2,y2"<<endl;
        cin>>x1>>y1>>x2>>y2;
        int abs_x=abs(x1-x2);
        int abs_y=abs(y1-y2);
        int g=gcd3(abs_x,abs_y);
        cout<<g-1<<endl;
        int x_step=(x2-x1)/g;
        int y_step=(y2-y1)/g;
        for(int i=0;i<=g;i++)///0时起点 g时终点;这是一个由起点按一定跨度,一步步到达终点的过程
        {
            cout<<"("<<x1+i*x_step<<","<<y1+i*y_step<<")"<<endl;
        }
    }
  • 相关阅读:
    判断Java Bean对象所有属性是否为空
    Java在服务器下删除文件、删除目录及目录下所有文件失败(file.delete() --> false)
    Java判断两个Integer类型的值是否相等
    Java将多张图片合并打包成zip格式进行下载
    Java给图片添加水印部署到服务器出现中文乱码
    SpringBoot+SpringMvc页面跳转404问题
    已解决:Caused by: java.lang.NoClassDefFoundError: org/springframework/util/AntPathMatcher$AntPatternComparator$PatternInfo
    ActiveMQ如何解决被重复消费和数据丢失的问题?
    高并发系统三大利器之降级
    高并发系统三大利器之限流
  • 原文地址:https://www.cnblogs.com/kimsimple/p/6680820.html
Copyright © 2011-2022 走看看