题目描述
给出一个二元一次方程ax+by=c,其中x、y是未知数,求它的正整数解的数量。
输入输出格式
输入格式:
第一行一个整数T,表示有T组数据。接下来T行,每行3个整数a、b、c。
输出格式:
输出T行,每行一个数,表示方程解的数量。如果正整数解的数量比65535还多输出“ZenMeZheMeDuo”。
题解
这个题一看就要先用扩展欧几里得求出一组x最小的整数解然后再计算出所有的解。
代码
#include<bits/stdc++.h> using namespace std; long long Exgcd(long long a, long long b, long long & x, long long & y) { if(b == 0) { x = 1, y = 0; return a; } int q = Exgcd(b, a % b, y, x); y -= x * (a / b); return q; } long long Get_ans_num(long long a, long long b, long long c, long long &x, long long &y) { const int maxnum = 70000; long long fa = 0, fb = 0; if(a == 0 && b == 0) { if(c == 0) return maxnum; else return 0; } if(a == 0) { if(c == 0) return maxnum; if(c % b == 0 && c /b > 0) return maxnum; return 0; } if(b == 0) { if(c == 0) return maxnum; if(c % a == 0 && c / a > 0) return maxnum; return 0; } if(c < 0) a = -a, b = -b, c = -c; if(a < 0) a = -a, fa = 1; if(b < 0) b = -b, fb = 1; long long gcd = Exgcd(a, b, x, y); if(c % gcd != 0) return 0; long long t = c / gcd; x = x * t, y = y * t; a = a / gcd, b = b / gcd, c = t; if(fa) a = -a, x = -x; if(fb) b = -b, y = -y; if(a < 0) a = -a, b = -b, c = -c; if(a * b < 0) return maxnum; x = x % b; for(;x <= 0;) x += b; y = (c - a * x) / b; if(y < 0) return 0; long long miny = y % a; for(;miny <= 0;) miny += a; if(miny > y) return 0; return (y - miny) / a + 1; } int main() { //freopen("fuction.in", "r", stdin); //freopen("fuction.out", "w", stdout); long long T, a, b, c, ans, x, y; scanf("%lld", &T); for(int i = 1; i <= T; ++ i) { scanf("%lld%lld%lld", &a, &b, &c); ans = Get_ans_num(a, b, c, x, y); if(ans <= 65535) printf("%lld ", ans); else printf("ZenMeZheMeDuo "); } }
关于扩展欧几里得的总结
- 扩欧与方程的通解
扩展欧几里得是用于求解方程 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.在用扩欧解方程时,若有负数,可通过方程式变形来处理