模拟7题解T1

方程的解

[扩展欧几里德]

首先进行特判,两个小时基本想到了,除了a!=0,b==0,a*c<0这种情况

其次就是一般情况:

首先exgcd求出ax+by=GCD(a,b)的一组任意解

然后两边同乘(c/GCD)使x,y成为原方程的一组任意解,

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #define int long long
 5 using namespace std;
 6 const int mx=65535;
 7 int read()
 8 {
 9     int f=1,x=0;char ch=getchar();
10     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
11     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
12     return f*x;
13 }
14 int exgcd(int a,int b,int &x,int &y)
15 {
16     if(!b){x=1,y=0;return a;}
17     int d=exgcd(b,a%b,x,y);
18     int tmp=x;x=y;y=tmp-(a/b)*y;
19     return d;
20 }
21 int a,b,c;
22 int  ans;
23 void work()
24 {
25     //特判出现0的情况
26     if(a==0&&b==0&&c==0){ans=mx+10;return;}
27     if(a==0&&b==0&&c!=0){ans=0;return;}
28     if(a==0||b==0)
29     {
30         if(c==0)   {ans=0;return;}
31         if(a==0)  swap(a,b);
32         if(a*c<0){ans=0;return;}
33         a=abs(a),c=abs(c);
34         if(c%a==0){ans=mx+10;return;}
35         else      {ans=0;return;}
36     }
37     //特判ab与c异号
38     if(a>0&&b>0&&c<=0){ans=0;return;}
39     if(a<0&&b<0&&c>=0){ans=0;return;}
40     //特判a,b异号
41     int x,y;
42     int d=exgcd(a,b,x,y);
43     if(c%d){ans=0;return;}
44     if(a*b<0){ans=mx+10;return;}//注意这两行代码顺序,反例3 -3 5:应先进行上一步判定c%d!=0
45     //abc同号时,可以先处理a==b==1和a+b==c两种特殊情况,拿到部分分
46     if(a<0) a=-a,b=-b,c=-c,d=-d;    
47 /*    if(a==1&&b==1)
48     {
49         if(c>=2)    ans=c-1;
50         else ans=0;
51         return;
52     }
53     if(a+b==c)   {ans=1;return;}*/
54     //再处理一般情况
55     ans=0;
56     x*=(c/d),y*=(c/d);//x,y成为原方程的一组特解
57     a/=d,b/=d,c/=d;//系数约分后使GCD(a,b)==1
58     x=(x%b+b)%b;//使得x成为符合条件的最小正整数,,通过+b避免负数
59     if(x==0)  x+=b;//注意x为0的特殊情况
60     int ymax=(c-a*x)/b;//x最小时求出y的最大值
61     y=(y%a+a)%a;
62     if(y==0) y+=a;//同理求y的最小值
63     ans=(ymax-y)/a+1;//对于ymin->ymax之间的y,对应的x可能不是整数,所以/a成为x是整数的个数,因为包括两端,所以+1
64     return;
65 }
66 signed main()
67 {
68     int T=read();
69     while(T--)
70     {
71         a=read(),b=read(),c=read();
72         work();
73         if(ans>mx)  puts("ZenMeZheMeDuo");
74         else printf("%lld\n",ans);
75     }
76 }
View Code

猜你喜欢

转载自www.cnblogs.com/casun547/p/11228307.html