zoukankan      html  css  js  c++  java
  • SGU 106 The equation 扩展欧几里德

    106. The equation

    time limit per test: 0.25 sec.
    memory limit per test: 4096 KB

    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+by=-c;
       扩展欧几里德求解;
       x=x0+b/gcd(a,b)*t;
       y=y0+a/gcd(a,b)*t;
    求x1<=x<=x2&&y1<=y<=y2的条件下,t的可行解;
       找到x的范围的t的可行解[lx,rx];
       同理 [ly,ry];
    ans=min(rx,ry)-max(lx,ly)+1;
    #include<bits/stdc++.h>
    using namespace std;
    #define ll __int64
    #define esp 1e-13
    const int N=1e3+10,M=1e6+1000,inf=1e9+10,mod=1000000007;
    void extend_Euclid(ll a, ll b, ll &x, ll &y)
    {
        if(b == 0)
        {
            x = 1;
            y = 0;
            return;
        }
        extend_Euclid(b, a % b, x, y);
        ll tmp = x;
        x = y;
        y = tmp - (a / b) * y;
    }
    ll gcd(ll a,ll b)
    {
        if(b==0)
            return a;
        return gcd(b,a%b);
    }
    int main()
    {
        ll a,b,c;
        ll lx,rx;
        ll ly,ry;
        scanf("%I64d%I64d%I64d",&a,&b,&c);
        scanf("%I64d%I64d",&lx,&rx);
        scanf("%I64d%I64d",&ly,&ry);
        c=-c;
        if(lx>rx||ly>ry)
        {
            printf("0
    ");
            return 0;
        }
        if (a == 0 && b == 0 && c == 0)
        {
            printf("%I64d
    ",(rx-lx+1) * (ry-ly+1));
            return 0;
        }
        if (a == 0 && b == 0)
        {
            printf("0
    ");
            return 0;
        }
        if (a == 0)
        {
            if (c % b != 0)
            {
                printf("0
    ");
                return 0;
            }
            ll y = c / b;
            if (y >= ly && y <= ry)
            {
                printf("%I64d
    ",rx - lx + 1);
                return 0;
            }
            else
            {
                printf("0
    ");
                return 0;
            }
        }
        if (b == 0)
        {
            if (c % a != 0)
            {
                printf("0
    ");
                return 0;
            }
            ll x = c / a;
            if (x >= lx && x <= rx)
            {
                printf("%I64d
    ",ry - ly + 1);
                return 0;
            }
            else
            {
                printf("0
    ");
                return 0;
            }
        }
        ll hh=gcd(abs(a),abs(b));
        if(c%hh!=0)
        {
            printf("0
    ");
            return 0;
        }
        else
        {
            ll x,y;
            extend_Euclid(abs(a),abs(b),x,y);
            x*=(c/hh);
            y*=(c/hh);
            if(a<0)
                x=-x;
            if(b<0)
                y=-y;
            a/=hh;
            b/=hh;
            ll tlx,trx,tly,trry;
            if(b>0)
            {
                ll l=lx-x;
                tlx=l/b;
                if(l>=0&&l%b)
                    tlx++;
                ll r=rx-x;
                trx=r/b;
                if(r<0&&r%b)
                    trx--;
            }
            else
            {
                b=-b;
                ll l=x-rx;
                tlx=l/b;
                if(l>=0&&l%b)
                    tlx++;
                ll r=x-lx;
                trx=r/b;
                if(r<0&&r%b)
                    trx--;
            }
            if(a>0)
            {
                ll l=-ry+y;
                tly=l/a;
                if(l>=0&&l%a)
                    tly++;
                ll r=-ly+y;
                trry=r/a;
                if(r<0&&r%a)
                    trry--;
            }
            else
            {
                a=-a;
                ll l=ly-y;
                tly=l/a;
                if(l>=0&&l%a)
                    tly++;
                ll r=ry-y;
                trry=r/a;
                if(r<0&&r%a)
                    trry--;
            }
            printf("%I64d
    ",(max(0LL,min(trry,trx)-max(tly,tlx)+1)));
            return 0;
        }
        return 0;
    }

  • 相关阅读:
    美国商务签证面试经历
    正则表达式匹配字符串中的数值部分并将其返回
    在WPF中使用水晶报表for vs2010的方法
    Wpf中用代码执行控件的单击事件
    WPF项目中使用水晶报表for vs2010时的一个找不到程序集的问题
    WinForm实现全屏方法
    wpf中将数据导出为Excel
    WinForm实现窗体上控件的自由拖动
    在WPF中使用WinForm控件方法
    多样、互动的WinForm UI设计与开发思路(Flash、Html等)
  • 原文地址:https://www.cnblogs.com/jhz033/p/5755075.html
Copyright © 2011-2022 走看看