zoukankan      html  css  js  c++  java
  • Lattice Point or Not UVA

    原文地址:https://www.cnblogs.com/zyb993963526/p/6783532.html

    题意:

    给定两个点A(x1,y1)和B(x2,y2),均为0.1的整数倍。统计选段AB穿过多少个整点。

    思路:

    做了这道题之后对于扩展欧几里得有了全面的了解。

    根据两点式公式求出直线 ,那么ax+by=c 中的a、b、c都可以确定下来了。

    接下来首先去计算出一组解(x0,y0),因为根据这一组解,你可以写出它的任意解,其中,K取任何整数。

    需要注意的是,这个 a' 和 b' 是很重要的,比如说 b' ,它代表的是x每隔 b' ,就会出现一个整点。

    所以这道题目的关键就是,我们先求出一组解,然后通过它的 b' 将x0改变成x,使得x在[x1,x2]区间之内,这样每 b' 个单位就有一个整点了,即

     

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<cmath>
    #include<map>
    using namespace std;
    
    typedef long long LL;
    double X1,Y1,X2,Y2;
    
    void gcd(LL a,LL b,LL& d,LL& x,LL& y)
    {
        if(!b)  {d=a;x=1;y=0;}
        else { gcd(b,a%b,d,y,x); y-=x*(a/b);}
    }
    
    LL solve()
    {
        LL x1=X1*10, y1=Y1*10, x2=X2*10, y2=Y2*10;
        if(x1==x2)                    //平行y轴
        {
            if(x1%10)  return 0;      //原来的X1为小数,肯定不是整点
            if(Y2<Y1)  swap(Y1,Y2);
            return floor(Y2)-ceil(Y1)+1;
        }
        if(y1==y2)
        {
            if(y1%10)  return 0;
            if(X2<X1)  swap(X1,X2);
            return  floor(X2)-ceil(X1)+1;
        }
        LL a=(y2-y1)*10, b=(x1-x2)*10, c=y2*x1-y1*x2;  //c相当于扩大了100倍,所以前面还得乘10
        LL d,x,y;
        gcd(a,b,d,x,y);
        if(c%d)   return 0;      //扩展欧几里得算法无解的判断
    
        x=x*c/d; y=y*c/d;        //获得一组整数解(x,y)
        b=abs(b/d);             //这里的b其实就是b'
    
        if(X1>X2)   swap(X1,X2);
        x1=ceil(X1);
        x2=floor(X2);
        if(x1>x2) return 0;
    
        x=x+(x1-x)/b*b;        //使x进入[x1,x2]的区间内
        if(x<x1)  x+=b;
        if(x>x2)  return 0;
        return (x2-x)/b+1;
    }
    
    int main()
    {
        //freopen("D:\input.txt","r",stdin);
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%lf%lf%lf%lf",&X1,&Y1,&X2,&Y2);
            LL ans = solve();
            printf("%lld
    ",ans);
        }
        return 0;
    }

    思路:

    做了这道题之后对于扩展欧几里得有了全面的了解。

    根据两点式公式求出直线 ,那么ax+by=c 中的a、b、c都可以确定下来了。

    接下来首先去计算出一组解(x0,y0),因为根据这一组解,你可以写出它的任意解,其中,K取任何整数。

    需要注意的是,这个 a' 和 b' 是很重要的,比如说 b' ,它代表的是x每隔 b' ,就会出现一个整点。

    所以这道题目的关键就是,我们先求出一组解,然后通过它的 b' 将x0改变成x,使得x在[x1,x2]区间之内,这样每 b' 个单位就有一个整点了,即

     

     
     
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    JQ_浏览器窗口改变触发
    5. 通过PHP反序列化进行远程代码执行
    2. 文件包含(150)
    1. md5 collision(50)
    4.xpath注入详解
    2.HTTP头注入
    1.5 xss漏洞修复
    1.4 DVWA亲测XSS漏洞
    1.如何绕过WAF(Web应用防火墙)
    1.3 xss原理分析与剖析(4)
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9325081.html
Copyright © 2011-2022 走看看