题目描述
给出一个二元一次方程ax+by=c,其中x、y是未知数,求它的正整数解的数量。
输入输出格式
输入格式:
第一行一个整数T,表示有T组数据。接下来T行,每行3个整数a、b、c。
输出格式:
输出T行,每行一个数,表示方程解的数量。如果正整数解的数量比65535还多输出“ZenMeZheMeDuo”。
题解
这个题一看就要先用扩展欧几里得求出一组x最小的整数解然后再计算出所有的解。
代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 long long Exgcd(long long a, long long b, long long & x, long long & y) 5 { 6 if(b == 0) 7 { 8 x = 1, y = 0; 9 return a; 10 } 11 int q = Exgcd(b, a % b, y, x); 12 y -= x * (a / b); 13 return q; 14 } 15 16 long long Get_ans_num(long long a, long long b, long long c, long long &x, long long &y) 17 { 18 const int maxnum = 70000; 19 long long fa = 0, fb = 0; 20 if(a == 0 && b == 0) 21 { 22 if(c == 0) return maxnum; 23 else return 0; 24 } 25 if(a == 0) 26 { 27 if(c == 0) return maxnum; 28 if(c % b == 0 && c /b > 0) return maxnum; 29 return 0; 30 } 31 if(b == 0) 32 { 33 if(c == 0) return maxnum; 34 if(c % a == 0 && c / a > 0) return maxnum; 35 return 0; 36 } 37 if(c < 0) a = -a, b = -b, c = -c; 38 if(a < 0) a = -a, fa = 1; 39 if(b < 0) b = -b, fb = 1; 40 long long gcd = Exgcd(a, b, x, y); 41 if(c % gcd != 0) return 0; 42 long long t = c / gcd; 43 x = x * t, y = y * t; 44 a = a / gcd, b = b / gcd, c = t; 45 if(fa) a = -a, x = -x; 46 if(fb) b = -b, y = -y; 47 if(a < 0) a = -a, b = -b, c = -c; 48 if(a * b < 0) return maxnum; 49 x = x % b; 50 for(;x <= 0;) x += b; 51 y = (c - a * x) / b; 52 if(y < 0) return 0; 53 long long miny = y % a; 54 for(;miny <= 0;) miny += a; 55 if(miny > y) return 0; 56 return (y - miny) / a + 1; 57 } 58 59 int main() 60 { 61 //freopen("fuction.in", "r", stdin); 62 //freopen("fuction.out", "w", stdout); 63 long long T, a, b, c, ans, x, y; 64 scanf("%lld", &T); 65 for(int i = 1; i <= T; ++ i) 66 { 67 scanf("%lld%lld%lld", &a, &b, &c); 68 ans = Get_ans_num(a, b, c, x, y); 69 if(ans <= 65535) printf("%lld\n", ans); 70 else printf("ZenMeZheMeDuo\n"); 71 } 72 }
关于扩展欧几里得的总结
- 扩欧与方程的通解
扩展欧几里得是用于求解方程 ax + by = gcd(a,b)的解的(要求a,b非负)。对于方程ax+by=gcd(a,b),知道一组特解x0,y0我们一定能够求出它的通解:
将其推广的话对于方程ax+by=c,我们首先要解的方程是ax+by=gcd(a,b)解为x0’,y0‘
若c|gcd(a,b),则令t=c/gcd(a,b),对于等式ax0‘+by0‘=gcd(a,b)两边同时乘以t就有等式a(tx0‘)+b(ty0‘)=gcd(a,b)*t=c,所以原方程的一组解就是x0=tx0‘,y0=ty0‘,而在这种情况下,我们能够得到它们的通解:
2.在二元一次方程组整数解中的一些特殊情况(ax+by=c)
-
- 若a==0且b==0,若有c==0,则有无数组解,但若c!=0则无解。
- 当a*b>0时整数解的组数有可能是有限的。
- 当a==0时若有c%b==0则有无数组解(x可取任意整数,y=(c/b)),当y>0时有无数组正整数解;b==0时亦然。
3.在用扩欧解方程时,若有负数,可通过方程式变形来处理
原文地址:https://www.cnblogs.com/2020pengxiyue/p/9314237.html
时间: 2024-10-18 17:41:37