zoukankan      html  css  js  c++  java
  • sgu106 求直线在某一矩形范围内经过的整点,扩展gcd

    sgu106  求直线在某一矩形范围内经过的整点,扩展gcd

    X - The equation
    Time Limit:250MS     Memory Limit:4096KB     64bit IO Format:%I64d & %I64u

    Description

    There is an equation ax + by + c = 0. Given a,b,c,x1,x2,y1,y2 you must determine, how many integer roots of this equation are satisfy to the following conditions : x1<=x<=x2,   y1<=y<=y2. Integer root of this equation is a pair of integer numbers (x,y).

    Input

    Input contains integer numbers a,b,c,x1,x2,y1,y2 delimited by spaces and line breaks. All numbers are not greater than 108 by absolute value。

    Output

    Write answer to the output.

    Sample Input

    1 1 -3
    0 4
    0 4
    

    Sample Output

    4
    题意:求解ax+bx+c=0在[x1,x2][y1,y2]经过的整点个数。
    思路:扩展gcd解出一个特解,再根据[x1,x2][y1,y2]解出两个k的范围,取交集即可。一个细节,先取交集再取整WA,先取整再取交集就过了,不知为何。。一个技巧,对取整数闭区间可以对两个double边界,下界向上取整ceil,上界向下取整floor,即可取到整数边界的闭区间。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<set>
    #include<map>
    #include<string>
    #include<math.h>
    #include<cctype>
    #define ll long long
    #define REP(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
    #define REPP(i,a,b,t) for(int (i)=(a);(i)<=(b);(i)+=(t))
    #define PII pair<int,int>
    #define fst first
    #define snd second
    #define MP make_pair
    #define PB push_back
    #define RI(x) scanf("%d",&(x))
    #define RII(x,y) scanf("%d%d",&(x),&(y))
    #define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))
    #define DRI(x) int (x);scanf("%d",&(x))
    #define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y))
    #define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d",&(x),&(y),&(z))
    #define RS(x) scanf("%s",s)
    #define RSS(x,y) scanf("%s%s",x,y)
    #define DRS(x) char x[maxn];scanf("%s",x)
    #define DRSS(x,y) char x[maxn],y[maxn];scanf("%s%s",x,y)
    #define MS0(a) memset((a),0,sizeof((a)))
    #define MS1(a) memset((a),-1,sizeof((a)))
    #define MS(a,b) memset((a),(b),sizeof((a)))
    #define ALL(v) v.begin(),v.end()
    #define SZ(v) (v).size()
    
    using namespace std;
    
    const int maxn=1000100;
    const int INF=(1<<29);
    const double EPS=0.0000000001;
    const double Pi=acos(-1.0);
    
    ll exgcd(ll a,ll b,ll &x,ll &y)
    {
        if(b==0){
            x=1;y=0;
            return a;
        }
        ll r=exgcd(b,a%b,x,y);
        ll t=y;
        y=x-a/b*y;
        x=t;
        return r;
    }
    
    int main()
    {
        ll a,b,c,x1,x2,y1,y2,x,y;
        while(cin>>a>>b>>c>>x1>>x2>>y1>>y2){
            c=-c;
            if(a==0&&b==0)
                if(c==0) cout<<(x2-x1+1)*(y2-y1+1)<<endl;
                else cout<<0<<endl;
            else if(a==0)
                if(c%b==0&&y1<=c/b&&c/b<=y2) cout<<x2-x1+1<<endl;
                else cout<<0<<endl;
            else if(b==0)
                if(c%a==0&&x1<=c/a&&c/a<=x2) cout<<y2-y1+1<<endl;
                else cout<<0<<endl;
            else{
                ll d=exgcd(a,b,x,y);
                if(c%d) cout<<0<<endl;
                else{
                    x*=c/d;y*=c/d;
                    double L1=(x1-x)*1.0*d/b,R1=(x2-x)*1.0*d/b;
                    if(L1>R1) swap(L1,R1);
                    double L2=(y-y1)*1.0*d/a,R2=(y-y2)*1.0*d/a;
                    if(L2>R2) swap(L2,R2);
                    ll Ld1=ceil(L1),Rd1=floor(R1);
                    ll Ld2=ceil(L2),Rd2=floor(R2);
                    ll L=max(Ld1,Ld2),R=min(Rd1,Rd2);
                    if(L>R) cout<<0<<endl;
                    else cout<<R-L+1<<endl;
                }
            }
        }
        return 0;
    }
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    查看详细linux系统信息的命令和方法
    linux下将当前目录下的文件名存到一个文本文件里
    详解linux下批量替换文件内容的三种方法(perl,sed,shell)
    将二维数组中某个值为空的数组进行删除!
    字符串截取,对数字,英文,汉字都可以
    根据二维数组的某列数值来对二维数组进行排序
    iOS开发之第三方分享QQ分享,史上最新最全第三方分享QQ方式实现
    iOS开发之第三方登录微博-- 史上最全最新第三方登录微博方式实现
    iOS开发之第三方登录微信-- 史上最全最新第三方登录微信方式实现
    iOS开发之第三方登录QQ -- 史上最全最新第三方登录QQ方式实现
  • 原文地址:https://www.cnblogs.com/--560/p/4583479.html
Copyright © 2011-2022 走看看