牛牛的方程式

PS:如果读过题了可以跳过题目描述直接到题解部分

暂无提交链接

题目

题目描述

牛牛最近对三元一次方程非常感兴趣。众所周知,三元一次方程至少需要三个方程组成一个方程组,才有可能得出一组解。

牛牛现在想要知道对于方程 ax+by+cz=d 中有没有至少存在一组 {x,y,z} 的解,且 x,y,z 都为整数,使得方程式成立。

输入格式

第一行输入一个正整数 T ,表示测试点中测试样例的组数。

接下来 T 行,每行四个整数 a,b,c,d 表示方程 ax+by+cz=d 中的 a,b,c,d

输出格式

如果至少存在一组 x,y,z 能够满足方程式等式成立,且 x,y,z 均为整数,请输出 "YES",否则请输出 "NO"。

样例

输入

2

3 1 2 0

2 8 8 3

输出

 YES

NO

解释 

1*3+(-1)*1+(-1)*2=0

得到一组  x,y,z 的解为 {1,-1,-1} 为整数使得等式成立,所以输出 "YES"。

不存在 x,y,z 为整数使得方程 2x+8y+8z=3 成立,所以输出 "NO"。

数据范围

对于 10% 的测试数据,保证 T=1,-10≤a,b,c≤10

对于 30% 的测试数据,保证 -100≤a,b,c≤100

对于 100% 的测试数据,保证 -10^18≤a,b,c≤10^18,1≤T≤100

题解

裴蜀定理(贝祖定理)

裴蜀定理 - OI Wiki

应用

这道题只用用裴蜀定理代换两次就好了。

第一次: ax+by=gcd(a,b)k

第二次: gcd(a,b)k+cz=gcd(gcd(a,b),c)m

不过需要注意,非常需要注意的是!!!!!!!gcd之前要特判!!!!!!两个数的大小和是否非零!!!!!!

代码实现

代码我基本上是直接暴力分类……

//牛牛的方程式
#include<iostream>
#include<cstdio>
using namespace std;
int t;
long long a,b,c,d;
long long e;

long long gcd(long long x,long long y){
	if(y==0){
		return x;
	}
	return gcd(y,x%y);
}

int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
		if(d==0){
			printf("YES\n");
			continue;
		}
		if(a==0){
			if(b==0){
				if(c==0){
					printf("NO\n");
				}
				else{
					if(d%c){
						printf("NO\n");
					}
					else{
						printf("YES\n");
					}
				}
			}
			else{
				if(c==0){
					if(d%b){
						printf("NO\n");
					}
					else{
						printf("YES\n");
					}
				}
				else{
					if(b>c){
						if(d%gcd(b,c)){
							printf("NO\n");
						}
						else{
							printf("YES\n");
						}
					}
					else{
						if(d%gcd(c,b)){
							printf("NO\n");
						}
						else{
							printf("YES\n");
						}
					}
				}
			}
		}
		else{
			if(b==0){
				if(c==0){
					if(d%a){
						printf("NO\n");
					}
					else{
						printf("YES\n");
					}
				}
				else{
					if(a>c){
						if(d%gcd(a,c)){
							printf("NO\n");
						}
						else{
							printf("YES\n");
						}
					}
					else{
						if(d%gcd(c,a)){
							printf("NO\n");
						}
						else{
							printf("YES\n");
						}
					}
				}
			}
			else{
				if(c==0){
					if(a>b){
						if(d%gcd(a,b)){
							printf("NO\n");
						}
						else{
							printf("YES\n");
						}
					}
					else{
						if(d%gcd(b,a)){
							printf("NO\n");
						}
						else{
							printf("YES\n");
						}
					}
				}
				else{
					if(a>b){
						e=gcd(a,b);
						if(e>c){
							if(d%gcd(e,c)){
								printf("NO\n");
							}
							else{
								printf("YES\n");
							}
						}
						else{
							if(d%gcd(c,e)){
								printf("NO\n");
							}
							else{
								printf("YES\n");
							}
						}
					}
					else{
						e=gcd(b,a);
						if(e>c){
							if(d%gcd(e,c)){
								printf("NO\n");
							}
							else{
								printf("YES\n");
							}
						}
						else{
							if(d%gcd(c,e)){
								printf("NO\n");
							}
							else{
								printf("YES\n");
							}
						}
					}
				}
			}
		}
	}
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月半流苏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值