方程的解
总之这题如果静下心来仔细想,拿个80分并不难
问题:扩欧只会板子,并未理解,扩欧解出来的是一组解而已,并没有最值等的特殊性。
ax+by=c必须在c能整除gcd(a,b)的情况下,此时会有n多组解,设d=gcd(a,b);x=(c/d)*x0+k*(b/d),y=(c/d)*x0-k*(a/d);
这题还是值得好好看看,因为特判情况可以搞到许多分。包括数据范围的特判,解的个数的特判。
先纪念一下能把所有特殊数据跑粗来的对拍生成数据:
1 #include<bits/stdc++.h>
2 using namespace std;
3 int random(int x){
4 return (long long)rand()*rand()%x;
5 }
6 int zo(){
7 int hh=random(100);
8 if(hh>50)return -1;
9 return 1;
10 }
11 int T,a,b,c;
12 int main(){
13 freopen("da.in","w",stdout);
14 srand(time(0));
15 T=random(100000)+1;
16 // cout<<zo()<<endl;
17 cout<<T<<endl;
18 while(T){
19 --T;
20 int he=random(8);
21 a=zo()*random(1000001);b=zo()*random(1000001);c=zo()*random(1000001);
22 switch(he){
23 case 0:{
24 break;
25 }
26 case 1:{
27 a=0;
28 break;
29 }
30 case 2:{
31 b=0;
32 break;
33 }
34 case 3:{
35 c=0;
36 break;
37 }
38 case 4:{
39 a=b=0;
40 break;
41 }
42 case 5:{
43 a=c=0;
44 break;
45 }
46 case 6:{
47 b=c=0;
48 break;
49 }
50 case 7:{
51 a=b=c=0;
52 break;
53 }
54 }
55 cout<<a<<" "<<b<<" "<<c<<endl;
56 }
57 }
AC代码:
1 #include<cstdio>
2 #include<cstring>
3 #include<iostream>
4 #include<cmath>
5 #define xian 65535
6 #define ll long long
7 using namespace std;
8 inline ll read(){
9 ll s=0,w=1;char ch=getchar();
10 while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
11 while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
12 return s*w;
13 }
14
15 ll T;
16 ll a,b,c;
17 ll ltmp;
18 ll exgcd(ll a,ll b,ll &x,ll &y){
19 if(!b){
20 x=1;y=0;
21 return a;
22 }
23 ll lgcd=exgcd(b,a%b,x,y);
24 ltmp=x;
25 x=y;
26 y=ltmp-a/b*y;
27 return lgcd;
28 }
29
30 int main(){
31 // freopen("da.in","r",stdin);
32 // freopen("te.out","w",stdout);
33 T=read();
34 while(T){
35 --T;
36 a=read();b=read();c=read();
37 //cout<<c<<endl;
38
39 if(a==0&&b==0){
40 if(!c){puts("ZenMeZheMeDuo");continue; }
41 else{puts("0");continue; }
42 }
43 if(!a){
44 if(c*b<0){puts("0");continue; }
45 else{
46 if(!c){puts("0");continue; }
47 if(c%b){puts("0");continue; }
48 else{puts("ZenMeZheMeDuo");continue; }
49 }
50 }
51 if(!b){
52 if(c*a<0){puts("0");continue; }
53 else{
54 if(!c){puts("0");continue; }
55 if(c%a){puts("0");continue; }
56 else{puts("ZenMeZheMeDuo");continue; }
57 }
58 }
59
60 if(a+b==c){puts("1");continue; }
61 if(a<0)a*=-1,b*=-1,c*=-1;
62 if(b>0&&c<0){puts("0");continue; }
63 if(b>0&&c>0){
64 if(a==1&&b==1){
65 if(c-1>xian)puts("ZenMeZheMeDuo");
66 else printf("%lld\n",(c-1));
67 continue;
68 }
69 }
70
71 ll x,y;
72 ll lin=exgcd(a,b,x,y);
73
74 if(c%lin){puts("0");continue; }
75 if(a*b<0){puts("ZenMeZheMeDuo");continue; }
76
77 ll xi=c/lin;
78 x*=xi;y*=xi;
79
80 if(x==0&&y==0){puts("0");continue; }
81 if(x<0&&y<0){puts("0");continue; }
82
83 ll jx=b/lin,jy=a/lin;
84 ll ans=0;
85
86 if(x<=0)ans=ceil(y*1.0/jy)-1-(-1*x/jx);
87 else if(y>=0)ans=ceil(x*1.0/jx)-1-(-1*y/jy);
88 else ans=ceil(x*1.0/jx)-1+ceil(1.0*y/jy);
89
90 if(ans<=0){puts("0");continue; }
91 if(ans>xian){puts("ZenMeZheMeDuo");continue; }
92
93 printf("%lld\n",ans);
94 }
95 return 0;
96 }