题目描述
给定两个整数a,b,
对于一次操作:选择一个正整数x,使a=a-x,b=b-2x或者a=a-2x,b=b-x
对于每次操作可以选择不同的x值,能否在任意次操作(可以为0次操作)后使得a,b同时等于0
输入
第—行一个整数T(1<=T<=100),表示有T组测试用例
随后有T组测试用例,每组—行中有两个整数a,b(0<=a,b<=1e9)
输出
输出T行,对于每个测试用例,如果有可能使a和b同时等于0,则为YES,否则为NO。
输入样例
4
5 9
6 9
2 3
1 1
输出样例
NO
YES
NO
NO
提示
样例说明:
对于 a = 6 , b = 9
第一次操作:x = 4,使 a = a - x = 2 ; b = b -2x = 1
第二次操作:x = 1,使 a = a - 2x = 0 ; b = b - x = 0
解题思路
首先我们要注意第一点它每一次操作的x是随机的,所以其实我在看题的时候挺蒙的,因为x随机,代入那个公式也是随机的,所以不会做
然后我就看它给的样例说明,因为这道题本来既然已经找不到规律了,就想办法通过提示,去找提示中的规律,然后根据规律去把样例写出来。
通过样例说明我得到了:
- 它第一次操作的x=4,这个数其实挺大了,但为什么没有用1,2,3或者5等数字呢,
- 我就假设它每一次的x就是a和b两个值中大的那个数能减2x还不小于0的最大值,在这里显然第一次操作中,a和b大的数是9,而(9-2x>=0)最大的解x为4,所以第一次操作的x为4
- 然后把x=4代入,并且a和b大的值-2x,小的值-x,得到第二次操作的a和b分别是1和2.
- 那么我们继续通过上面我假设的方式继续,因为1和2比,2大,那么(2-2x >= 0)最大的解x为1.
- 然后我们把x = 1代入刚好a和b同时都为0了,就可以结束了,可以判断为YES了
通过上面对样例说明的分析,我们可以假设出这道题的思路
- 得到a和b的最大值
- 通过得到的最大值的到这一次的x
- 将得到的x代入得到对应的a和b
- 判断a和b是否同时为0,这个就可以直接推出循环了,不用再进行下一轮了。
- 有一个以上的已经小于0了,这个也要推出循环,但这个是失败的,也就是打印NO
- 还有当a和b相等但不为0的时候,那么这个可以得到直接就为NO,因为相同的值,一个减x,一个减2x,我想能为0的可能不大
代码
import java.util.Scanner;
/**
*
* @author hf
*
*/
public class Blogs1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt(); //几组测试用例
// 输入测试用例,插入到数组当中去
int [][] arr = new int[n][2];
for (int i = 0; i < n; i++) {
for (int j = 0; j < 2; j++) {
arr[i][j] = scanner.nextInt();
}
}
//
int x = 0; // 正整数x,或者可以叫自变量
int max = 0; //得到a和b中较大的值,用来代入-2x的式子
int min = 0; //得到a和b中较小的值,用来代入-x的式子
for (int i = 0; i < n; i++) {
// 因为不知道能到第几轮结束,故使用true
while (true) {
x = f(arr[i][0], arr[i][1]); //得到x
// 为NO 并且跳出循环的可能条件,这个-1是我自己把(a=b&&a!=0)返回的x设为的-1,这个可以随意
if (x == -1 || arr[i][0]*arr[i][1] < 0) {
System.out.println("NO");
break;
}
// 得到这一组测试用例的最大值和最小值
if (arr[i][0] > arr[i][1]) {
max = arr[i][0];
min = arr[i][1];
}else {
min = arr[i][0];
max = arr[i][1];
}
// System.out.println(max);
// System.out.println(min);
// 将最大值和最小值代入相对应的式子当中去
arr[i][0] = max -(2*x);
arr[i][1] = min - x;
// System.out.println(arr[i][0]);
// System.out.println(arr[i][1]);
// 为 YES并且跳出循环的可能条件
if (x == 0 || (arr[i][0] == 0 && arr[i][1] == 0) ) {
System.out.println("YES");
break;
}
}
}
scanner.close();
}
/**
* 得到自变量x
* @param a
* @param b
* @return
*/
public static int f(int a ,int b) {
// a和b相等时,直接放回x为0,用来跳出循环
if (a == b && a != 0) {
return -1;
}
//得到x的式子,这个其实和 Math.max(a, b)-2x>=0一个道理
int x = (Math.max(a, b))/2;
return x;
}
}