The equation----扩展欧几里得

题目:http://acm.sgu.ru/problem.php?contest=0&problem=106

问题在于:如何处理边界问题。

long long输入用"%I64d"。

源代码:

#include <stdio.h>
typedef  long long ll;

ll a,b,c,d;
ll x,y,x1,x2,y1,y2;
ll p,q,ans,p1,q1;
ll mn,mx;

ll extend_gcd(ll a,ll b,ll &x ,ll &y)
{
    ll t,ans;
    if(b==0)  {x=1; y=0;  return a;  }
    else
    {
        ans=extend_gcd(b,a%b,x,y);
        t=x;
        x=y;
        y=t-a/b*y;
    }
    return ans;
}

ll max(ll a,ll b)
{
    if(a>b)  return a;
    else   return b;
}

ll min(ll a,ll b)
{
    if(a>b)  return b;
    else  return a;
}

ll ok(ll a)
{
    if(a<0)
    return -a;
    return a;
}
ll swap(ll &a,ll &b)
{
    ll t;
    t=a;
    a=b;
    b=t;
}
int main()
{
    int f=1,f1=1;
   // printf("%d\n",(int)-5.6);
    scanf("%I64d %I64d %I64d",&a,&b,&c);
    scanf("%I64d %I64d %I64d %I64d",&x1,&x2,&y1,&y2);
    ans=0;
    if(a==0&&b==0)
    {
        if(c!=0) ans=0;
        else
        ans=(x2-x1+1)*(y2-y1+1);
        printf("%I64d\n",ans);
        return 0;
    }
    if(a==0)
    {
        if(-c%b==0&&-c/b>=y1&&-c/b<=y2)
           ans=x2-x1+1;
        else
           ans=0;
       printf("%I64d\n",ans);
        return 0;
    }
    if(b==0)
    {
        if(-c%a==0&&-c/a>=x1&&-c/a<=x2)
           ans=y2-y1+1;
        else
           ans=0;
       printf("%I64d\n",ans);
        return 0;
    }
    d=extend_gcd(a,b,x,y);
    x=x*(-c)/d;
    y=y*(-c)/d;
    if(-c%d!=0)
    {
        printf("0\n");   return 0;
    }
    if(b*d>0)  f=1;
    else  f=-1;
    if(a*d>0)  f1=1;
    else  f1=-1;
    if(x1>x)
    {
        if((x1-x)*d%b==0)  p=ok((x1-x)*d/b);
        else
        p=ok((x1-x)*d/b)+1;
    }
    else
    p=-ok((x1-x)*d/b);
    if(x2>x)
        q=ok((x2-x)*d/b);
    else
    {
        if((x2-x)*d%b==0)  q=-ok((x2-x)*d/b);
        else
        q=-ok((x2-x)*d/b)-1;
    }
    if(y1>y)
    {
        if((y1-y)*d%a==0)  p1=ok((y1-y)*d/a);
        else
        p1=ok((y1-y)*d/a)+1;
    }
    else
    p1=-ok((y1-y)*d/a);
    if(y2>y)
        q1=ok((y2-y)*d/a);
    else
    {
        if((y2-y)*d%a==0)  q1=-ok((y2-y)*d/a);
        else
        q1=-ok((y2-y)*d/a)-1;
    }
     if(f*p>f*q)   swap(p,q);
     if(-f1*p1>-f1*q1)  swap(p1,q1);
     mn=max(f*p,-f1*p1);
     mx=min(f*q,-f1*q1);
     if(mn>mx)  ans=0;
     else
     ans=mx-mn+1;
     printf("%I64d\n",ans);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值