code1213 解的个数 扩展欧几里得

很不错的题,加深了我对exgcd的理解

(以前我认为做题就是搜索、dp...原来数学也很重要)

理解了几个小时,终于明白了。但我什么都不打算写。

看代码吧:

#include<iostream>
using namespace std;

int exgcd(int a,int b,int& x,int&y){//扩展欧几里得 
    if(b==0){
        x=1; y=0;
        return a;
    }
    int x2,y2;
    int d=exgcd(b,a%b,x2,y2);
    x=y2; y=x2-(a/b)*y2;
    return d;
}

int main(){
    int T; cin>>T;
    while(T--){
        int a,b,c,lx,hx,ly,hy;
        cin>>a>>b>>c>>lx>>hx>>ly>>hy;
        c=-c;
        if(lx>hx||ly>hy||(a==0&&b==0&&c!=0)){cout<<0<<endl; continue;}
        if(a==0||b==0){
            long long num_x,num_y;
            if(a==0)num_x=hx-lx+1;
            else if(c%a==0&&(c/a)<=hx&&(c/a)>=lx)num_x=1;
            else num_x=0;
            if(b==0)num_y=hy-ly+1;
            else if(c%b==0&&(c/b)<=hy&&(c/b)>=ly)num_y=1;
            else num_y=0;
            cout<<num_x*num_y<<endl;
            continue;
        }
        int x,y;
        int d=exgcd(a,b,x,y);
        if(c%d!=0){cout<<0<<endl; continue;}
        int k=c/d;
        x*=k; y*=k;
        a/=d; b/=d;
//        cout<<x<<' '<<y<<endl;
        if(x<lx){
            while(x<lx){
                x+=b;
                y-=a;
            }
        }
        else{
            while(x>=lx){
                x-=b;
                y+=a;
            }
            x+=b; y-=a;
        }
        
        long long ans=0;
        while(x<=hx){
            if(y<=hy&&y>=ly){
                ans++;
//                cout<<x<<' '<<y<<endl;
            }
            x+=b;
            y-=a;
        }
        cout<<ans<<endl;
    }
}

 

posted @ 2016-07-10 14:31  FuTaimeng  阅读(248)  评论(0编辑  收藏  举报