SGU 106 扩展欧几里得

来源:互联网 发布:法医秦明网络剧百度云 编辑:程序博客网 时间:2024/06/16 07:49

真的是奇怪的题目。有很多大神的东西。

/*  解ax+by+c=0在[x1,x2] [y1,y2]范围内解的个数   稍微玩一下扩展欧几里得  解出一组解,利用通解公式得到通解个数   注意多组数据 */#include <stdio.h>#include <stdlib.h>long long a,b,c,x1,x2,ya,y2;long long x,y;long long ans=0;int gcd(int a,int b){  int tmp,t;  if (b==0)  {    x=1;    y=0;    return a;  }  tmp=gcd(b,a%b);  t=x;  x=y;  y=t-a/b*y;  return tmp;}int max(int a,int b){  if (a>b) return a;  return b;}int min(int a,int b){  return a+b-max(a,b);}void work(){  int d,p,k1,k2,k3,k4;  if (a==0 && b==0)  {    if (c==0)      ans = (x2-x1+1) * (y2-ya+1);  }  else if (a==0 && b!=0) //装换成了y的一次方程  {    if (c%b==0){  if (ya<=c/b && c/b<=y2)    ans=1;}   }   else if (a!=0 && b==0) //装换成了x的一次方程  {    if (c%a==0)    {  if (x1<=c/a && c/a<=y2)     ans=1;}  }   else   {    d=gcd(a,b);    if (c%gcd(a,b)==0) //判断方程是否有解{  p=c/d;  /*    关于这个奇怪东西的通解公式ax+by=c (c≡0(mod gcd(a,b)))令c0=c/gcd(a,b); x=x0*c0+k*b;y=y0*c0-k*a;    x1<=x0*c0+k*b<=x2    (x1-x0*c0)/b <=k <= (x2-x0*c0)/b同理可以得到 y给k界定的范围ya<=y0*c0-k*a<=y2     (y0*c0-y2)/a<=k<=(y0*c0-ya)/a   */ } k1=(x1-x*p)/b;k2=(x2-x*p)/b;k3=(y*p-y2)/a;k4=(y*p-ya)/a;ans=min(k2,k4)-max(k1,k3)+1;if (ans<0)  ans=0;  }  printf("%I64d\n",ans);}void init(){  while (~scanf("%I64d%I64d%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&x1,&x2,&ya,&y2))  {    c*=-1;    work();   }}int main(){  init();  return 0;} 


0 0
原创粉丝点击