总之这题如果静下心来仔细想,拿个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 }