NOIP模拟赛方程的解

貌似是扩欧的裸题,我暴力骗了80分

特判的情况就是a/b/c=0时,a+b=c时,a*b<0时,自己手模就知道了

扩欧的话我们由一般式可以发现这个方程有无数组解,那么因为我们限制了必须是正整数,所以个数有限,自己推一下公式就行啦

代码

//By AcerMo
#include
#include
#include
#include
#include
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch>'9'||ch<'0') {if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*f;
}
inline int exgcd(int a,int b,int &x,int &y)
{
	if (!b) return (x=1,y=0),a;
	int d=exgcd(b,a%b,x,y);
	int z=x;x=y;y=z-(a/b)*y;
	return d;
}
int main()
{
	int t=read();
	while (t--)
	{
		int a=read(),b=read(),c=read();
		if (a<0&&b<0) a=-a,b=-b,c=-c;
		if (a==0) 
			if (c%b==0&&c/b>0) {puts("ZenMeZheMeDuo");continue;}
				else {puts("0");continue;}
		if (b==0)
			if (c%a==0&&c/a>0) {puts("ZenMeZheMeDuo");continue;}
				else {puts("0");continue;}
		if (a+b==c) {puts("1");continue;}
		int d,x,y;d=exgcd(a,b,x,y);
		if (c%d) {puts("0");continue;}
		if (a*b<0) {puts("ZenMeZheMeDuo");continue;}
		int e=c/d,k=a*b/d;x*=e;y*=e;x%=k/a;
		if (x<=0) x+=k/a;y=(c-a*x)/b;
		if (y<0) {puts("0");continue;}
		int ans=(y/(k/b))-((y%(k/b))==0)+1;
		if (ans>65535) puts("ZenMeZheMeDuo");
		else printf("%d\n",ans);
	}
	return 0;
}


你可能感兴趣的:(数论&&组合数学,扩展欧几里得)