zoukankan      html  css  js  c++  java
  • SGU106 The equation

    106. The equation

    time limit per test: 0.5 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
    题解:运用扩展欧几里得解二元一次方程。我们可以找出一对整数(x,y),使得方程ax+by=gcd(a,b)。因为gcd(a,b)=gcd(b,a%b),所以ax+by=bx'+(a%b)y',因为a%b=a-a/b*b;所以ax+by=ay'+b(x'-(a/b)*y').
    即:
    x=y';
    y=x'-(a/b)*y';这样运用迭代法我们就可以求出(x,y)。
    扩展欧几里得算法代码:(摘自刘汝佳大神的《算法竞赛入门经典》(P179)
    1 void gcd(int a,int b,int& d,int& x,int& y)
    2 {
    3    if(!b){d=a; x=1; y=0;}
    4   else{gcd(b,a%b,d,y,x);y-=x*(a/b);}
    5 }

    当我们运用上述方法求出ax+by=gcd(a,b)之后,假设解为(x1,y1)我们就可以用来求ax+by=c的一组解(x0,y0),设k=c%gcd(a,b),如果k!=0,即c不是gcd(a,b)的倍数,那么此方程无整数解。

    如果不等于0,那么a(x1*c/gcd(a,b))+b(y1*c/gcd(a,b))=c。所以x0=x1*c/gcd(a,b),y0=y1*c/gcd(a,b)。其余的整数解可以写成这样(x0+kb',y0-ka'),其中b'=b/gcd(a,b),a'=a/gcd(a,b)。具体推导过程请看《算法竞赛入门经典》179...记住即可。。。

    对于此题我们只要枚举K,使得:

    x1<=x0+kb'<=x2

    y1<=y0-ka'<=y2

    直接解出两个不等式的解,然后求交集即得到了K的范围,K的范围长度+1也即所有整数解的数量。

    注意精度问题以及a,b,c的正负。

    View Code
      1 #include<stdio.h>
      2 #include<math.h>
      3 #include<stdlib.h>
      4 typedef struct
      5 {
      6     long long d;
      7     long long x;
      8     long long y;
      9 } NODE;
     10 NODE gcd(long long a,long long b)
     11 {
     12     NODE s,p;
     13     if(!b)
     14     {
     15         s.x=1;
     16         s.y=0;
     17         s.d=a;
     18         return s;
     19     }
     20     s=gcd(b,a%b);
     21     p.x=s.x;
     22     s.x=s.y;
     23     s.y=p.x-(a/b)*s.y;
     24     return s;
     25 
     26 }
     27 long long max(long long a,long long b)
     28 {
     29     return a>b?a:b;
     30 }
     31 long long min(long long a,long long b)
     32 {
     33     return a<b?a:b;
     34 }
     35 
     36 int main(void)
     37 {
     38     long long a,b,c,x1,x2,y1,y2,ll,rr,tt;
     39     scanf("%lld%lld%lld",&a,&b,&c);
     40     scanf("%lld%lld",&x1,&x2);
     41     scanf("%lld%lld",&y1,&y2);
     42     if(a==0&&b==0)
     43     {
     44         if(!c)printf("%lld\n",(x2-x1+1)*(y2-y1+1));
     45         else
     46             printf("0\n");
     47     }
     48     else if(a==0&&b!=0)
     49     {
     50         if(c%b==0&&(c/b)>=y1&&(c/b)<=y2)
     51             printf("%lld\n",x2-x1+1);
     52         else
     53             printf("0\n");
     54     }
     55     else if(a!=0&&b==0)
     56     {
     57         if(c%a==0&&(c/a)>=x1&&(c/a)<=x2)
     58             printf("%lld\n",y2-y1+1);
     59         else
     60             printf("\n");
     61     }
     62     else
     63     {
     64         c=-c;
     65         if(c<0)
     66         {
     67             a=-a;
     68             b=-b;
     69             c=-c;
     70         }
     71         if(a<0)
     72         {
     73             a=-a;
     74             tt=x1;
     75             x1=-x2;
     76             x2=-tt;
     77            }
     78            if(b<0)
     79         {
     80             b=-b;
     81             tt=y1;
     82             y1=-y2;
     83             y2=-tt;
     84            }
     85         NODE s=gcd(a,b);
     86         if(c%s.d)
     87             printf("0\n");
     88         else
     89         {
     90 
     91             s.x*=(c/s.d);
     92             s.y*=(c/s.d);
     93             printf("%lld %lld\n",s.x,s.y);
     94             ll=max(ceil((double)(x1-s.x)*s.d/b),ceil((double)(s.y-y2)*s.d/a));
     95             rr=min(floor((double)(x2-s.x)*s.d/b),floor((double)(s.y-y1)*s.d/a));
     96             if(ll>rr)
     97                 printf("0\n");
     98             else
     99                 printf("%lld\n",rr-ll+1);
    100         }
    101     }
    102     return 0;
    103 }
     
  • 相关阅读:
    linux 下安装web开发环境
    Nginx服务器之 Nginx的基本配置
    Nginx服务器之基础学习
    java反射 之 反射基础
    java IO流 之 其他流
    java IO流 之 字符流
    java IO流 之 字节流
    java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
    java线程 公平锁 ReentrantLock(boolean fair)
    MarkdownPad 2破解
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/2956835.html
Copyright © 2011-2022 走看看