数字转化

题目描述

给定两个整数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随机,代入那个公式也是随机的,所以不会做
然后我就看它给的样例说明,因为这道题本来既然已经找不到规律了,就想办法通过提示,去找提示中的规律,然后根据规律去把样例写出来。
通过样例说明我得到了:

  1. 它第一次操作的x=4,这个数其实挺大了,但为什么没有用1,2,3或者5等数字呢,
  2. 我就假设它每一次的x就是a和b两个值中大的那个数能减2x还不小于0的最大值,在这里显然第一次操作中,a和b大的数是9,而(9-2x>=0)最大的解x为4,所以第一次操作的x为4
  3. 然后把x=4代入,并且a和b大的值-2x,小的值-x,得到第二次操作的a和b分别是1和2.
  4. 那么我们继续通过上面我假设的方式继续,因为1和2比,2大,那么(2-2x >= 0)最大的解x为1.
  5. 然后我们把x = 1代入刚好a和b同时都为0了,就可以结束了,可以判断为YES了

通过上面对样例说明的分析,我们可以假设出这道题的思路

  1. 得到a和b的最大值
  2. 通过得到的最大值的到这一次的x
  3. 将得到的x代入得到对应的a和b
  4. 判断a和b是否同时为0,这个就可以直接推出循环了,不用再进行下一轮了。
  5. 有一个以上的已经小于0了,这个也要推出循环,但这个是失败的,也就是打印NO
  6. 还有当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;
	}
}

样例答案

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值