sgu-106-The equation

这题写了很久了,也看了许多题解。。可是发现都好复杂,看不懂啊,果然智商是硬伤。

虽然知道这题是扩展欧几里德算法。。但是对与ax+by=c中系数的正负处理的不好,偶然看一题解发现处理的很好就抄袭了过来。Orz大神

http://blog.csdn.net/jerryihuang/article/details/7992068

这道题各种坑啊,各种讨论,各种bug,不过倒是学到不少,至少扩展欧几里德会用了,,,泪啊

//求的是ax+by=gcd(a,b)的解,其中d=gcd(a,b),注意a>b,并且最好把a,b变成正数计算

void
exgcd(LL a,LL b,LL &d,LL &x,LL &y) { if(!b){d=a;x=1;y=0;} else{exgcd(b,a%b,d,y,x);y-=x*(a/b);} }

 //先算出ax+by=gcd(a,b)的解x1,y1,d=gcd(a,b),然后ax+by=c的一组解是x=x1*c/d,y=y1*c/d;(注意:若c%d!=0,则无解)

//又因为若ax+by=c的一组解为(x0,y0),则它的任意解都可以写成(x0+kb',y0-ka'),其中a'=a/gcd(a,b),b'=b/gcd(a,b),k取任意值

// File Name: 106.cpp
// Author: zlbing
// Created Time: 2013/2/28 20:19:38

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
{
    if(!b){d=a;x=1;y=0;}
    else{exgcd(b,a%b,d,y,x);y-=x*(a/b);}
}
int main(){
    LL a,b,c,d,x,y,x1,x2,y1,y2;
    while(~scanf("%I64d%I64d%I64d",&a,&b,&c))
    {
        scanf("%I64d%I64d",&x1,&x2);
        scanf("%I64d%I64d",&y1,&y2);
        if(a==0||b==0)
        {
            if(a==0&&b){
                if(c%b||c/b>y2||c/b<y1)printf("0\n");
                else {
                    printf("%I64d\n",x2-x1+1);
                }
            }
            else if(b==0&&a){
                if(c%a||c/a>x2||c/a<x1)printf("0\n");
                else {
                    printf("%I64d\n",y2-y1+1);
                }
            }
            else {
                if(c==0)printf("%I64d\n",(y2-y1+1)*(x2-x1+1));
                else printf("0\n");
            
            }
            continue;
        }
        if(c<0)c=-c;
        else{
            a=-a;b=-b;
        }
        if(a<0){
            a=-a;
            x1=-x1;
            x2=-x2;
            swap(x1,x2);
        }
        if(b<0){
            b=-b;
            y1=-y1;
            y2=-y2;
            swap(y1,y2);
        }
        LL d,x,y;
        if(a<b){
            exgcd(b,a,d,y,x);
        }
        else exgcd(a,b,d,x,y);
        if(c%d){
            printf("0\n");
            continue;
        }
        a=a/d;
        b=b/d;
        c=c/d;
        while(x<x1){
            x+=b;
            y-=a;
        }
        while(x>x2){
            x-=b;
            y+=a;
        }
        LL ans=0;
        x=x*c;y=y*c;
        while(x<=x2){
            if(ans)break;
            if(x>=x1&&x<=x2&&y>=y1&&y<=y2)ans++;
            if(ans)break;
            x+=b;y-=a;
        }
        while(x>=x1){
            if(ans)break;
            if(x>=x1&&x<=x2&&y>=y1&&y<=y2)ans++;
            if(ans)break;
            x-=b;y+=a;
        }
     //将x,y暴力加或减,使x,y都在取值区间里
if(ans){ LL a1=(x2-x)/b;LL b1=(y-y1)/a; ans+=min(a1,b1); a1=(x-x1)/b;b1=(y2-y)/a; ans+=min(a1,b1); } printf("%I64d\n",ans); } return 0; }

 

posted @ 2013-03-03 02:04  z.arbitrary  阅读(315)  评论(0编辑  收藏  举报