这道题当时感觉是一道几乎纯考扩展欧几里得的题,然而板子忘了……于是乎这道题被我放在第二个打。
不得不说出题人相当良心,给了大把的暴力分前20分就是c-1,20~40暴力枚举,40~60输出1。白送的60分就到手了。
然而难得是后40分,我们可以先通过扩展欧几里得先求出x最小整数解,然后首先,自己本身就无解的方程输出0就好了,其次,如果a,b中有一个为零那么就是无限解如果都为0就看c,如果异号就是无限解等等等等特判,然后就没什么了,注意要开long long,细节真心坑,而且特判的顺序也极其重要。
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include<cstring> 5 #include<queue> 6 #include<algorithm> 7 #include<cmath> 8 #include<vector> 9 using namespace std; 10 int a,b,c,t; 11 long long x,y; 12 int exgcd(int a,int b,int c,long long &x,long long &y) 13 { 14 if(!b) 15 { 16 y=0; 17 x=c/a; 18 return a; 19 } 20 int t=exgcd(b,a%b,c,y,x); 21 y-=(a/b)*x; 22 return t; 23 } 24 int main() 25 { 26 scanf("%d",&t); 27 while(t--) 28 { 29 scanf("%d%d%d",&a,&b,&c); 30 if((!a)&&(!b)) 31 { 32 if(!c) 33 printf("ZenMeZheMeDuo\n"); 34 else 35 printf("0\n"); 36 continue; 37 } 38 if(c<0) 39 a=-a,b=-b,c=-c; 40 bool fa=0,fb=0; 41 if(a<0) 42 { 43 a=-a;fa=1; 44 } 45 if(b<0) 46 { 47 b=-b;fb=1; 48 } 49 long long x,y; 50 int gy=exgcd(a,b,c,x,y); 51 if(a*x+b*y!=c) 52 { 53 printf("0\n"); 54 continue; 55 } 56 if(fa)a=-a,x=-x; 57 if(fb)b=-b,y=-y; 58 if(a==0) 59 { 60 if(y<=0) printf("0\n"); 61 else printf("ZenMeZheMeDuo\n"); 62 continue; 63 } 64 65 if(b==0) 66 { 67 if(x<=0) printf("0\n"); 68 else printf("ZenMeZheMeDuo\n"); 69 continue; 70 } 71 if((a>0&&b<0)||(a<0&&b>0)) 72 { 73 printf("ZenMeZheMeDuo\n"); 74 continue; 75 } 76 if(a<0) a=-a,b=-b,c=-c; 77 a/=gy,b/=gy,c/=gy; 78 x%=b; 79 while(x<=0)x+=b; 80 int t=(c-a*x)/b; 81 long long my=t%a; 82 while(my<=0) my+=a; 83 int ans=0; 84 if(my<=t) ans=(t-my)/a+1; 85 if(ans<=65535)printf("%d\n",ans); 86 else printf("ZenMeZheMeDuo\n"); 87 } 88 return 0; 89 }
时间: 2024-10-27 19:57:36