zoukankan      html  css  js  c++  java
  • codevs 1213 解的个数

    题目描述 Description

    已知整数x,y满足如下面的条件:

    ax+by+c = 0

    p<=x<=q

    r<=y<=s

    求满足这些条件的x,y的个数。

    输入描述 Input Description

    第一行有一个整数nn<=10),表示有n个任务。n<=10

    以下有n行,每行有7个整数,分别为:a,b,c,p,q,r,s。均不超过108。

    输出描述 Output Description

    n行,第i行是第i个任务的解的个数。

    样例输入 Sample Input

    2

    2 3 -7 0 10 0 10

    1 1 1 -10 10 -9 9

    样例输出 Sample Output

    1

    19

    思路:

    扩展欧几里得,特判是一次函数的情况。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #define ll long long
    using namespace std;
    ll n,a,b,c,p,q,r,s,ans;
    void exgcd(ll a,ll b,ll &x,ll &y)
    {
        if(!b)
        {
            x=1;
            y=0;
            return ;
        }
        exgcd(b,a%b,y,x);
        y-=x*(a/b);
    }
    void slove()
    {
        int t=__gcd(a,b);
        c*=-1;
        if(!a&&!b)
        {
            if(c||p>q||r>s)
              printf("0
    ");
            else
              printf("%lld
    ",(q-p+1)*(s-r+1));
            return ;
        }
        if(!a)
        {
            ll d=c/b;
            if(d>=r&&d<=s&&!(c%b))
              printf("1
    ");
            else
              printf("0
    ");
            return ;
        }
        if(!b)
        {
            ll d=c/a;
            if(d>=p&&d<=q&&!(c%a))
              printf("1
    ");
            else
              printf("0
    ");
            return ;
        }
        if(c%t)
        {
            printf("0
    ");
            return ;
        }
        ll x=0,y=0;
        ans=0;
        exgcd(a,b,x,y);
        x=x*c/t;
        y=y*c/t;
        a/=t,b/=t;
        int e=0;
        if(x<p)
        {
            while(x+e*b<p) 
              e++;
            while(x+e*b<q)
            {
                if(r<=y-e*a&&y-e*a<=s) 
                  ans++;
                e++;
            }
        }
        else 
          if(x>q)
          {
                  while(x-e*b>q) 
                    e++;
                  while(x-e*b>p)
                  {
                      if(r<=y+e*a&&y+e*a<=s)
                        ans++;
                      e++;
                  }
          }
          else 
            if(x>=p&&x<=q)
            {
                while(x+e*b<=q)
                {
                    if(r<=y-e*a&&y-e*a<=s) 
                      ans++;
                    e++;
                }
                e=-1;
                while(x+e*b>=p)
                {
                    if(r<=y-e*a&&y-e*a<=s) 
                      ans++;
                    e--;
                }
            }
        printf("%lld
    ",ans);
    }
    int main()
    {
        int i,j;
        cin>>n;
        while(n--)
        {
            cin>>a>>b>>c>>p>>q>>r>>s;
            slove();
        }
        return 0;
    }
  • 相关阅读:
    python之private variable
    python实例、类方法、静态方法
    python常用option
    access
    FD_CLOEXEC
    fork后父子进程文件描述问题
    split
    信号
    kill
    进程组&Session
  • 原文地址:https://www.cnblogs.com/jyhywh/p/6055532.html
Copyright © 2011-2022 走看看