题面
Today, Alex wants to build a parkour course for Steve to train his parkour skills on. A parkour course is a sequence of integer coordinates on the plane. Here, a contiguous pair of coordinates is called a move, denoted as .
Alex knows that Steve can only perform the following types of moves:
- ;
- ;
- .
Note that Steve will not perform any other type of moves. For example, Steve can perform and , but will never perform moves such as , , or (even though they may look very easy).
You are given an integer coordinate on the plane.
Please determine if it is possible to make a parkour course that satisfies the following conditions:
- ;
- ;
- The parkour course only consists of moves that Steve can perform.
Input
Each test contains multiple test cases. The first line contains the number of test cases (). The description of the test cases follows.
The only line of each test case contains two integers and (, ).
Output
If it is possible to make a parkour course that satisfies the conditions, output “YES” on a separate line.
If it is impossible to make a parkour course that satisfies the conditions, output “NO” on a separate line.
You can output the answer in any case. For example, the strings “yEs”, “yes”, and “Yes” will also be recognized as positive responses.
思路
开始的时候,想使用dfs进行暴力搜索,从给定的目标坐标 x, y 一直逆推,检查是否为0
但是这个方法时间复杂度过高且冗余,所以我们需要换一个更简单的方法
注意到,若分别执行 ,, 次三种动作(顺序任意),会有下面的方程:
通过消元,可以得到:
代入第一个方程:
化简得到:
由 ,, 三个量的意义可知,满足不等式:
因此,我们需要让这个不等式成立,因此令 ,先计算是否满足 ,同时, 应该非负:
if (d < 0 || d % 3 != 0) { cout << "NO\n"; continue;}之后,当这个判定成功之后,我们需要得到 ,因此我们令
同时,由:,且a非负,可以得到:
我们基于上面的不等式,对 可以移项得到:
这里,由于 也是非负,所以有:
因此,我们得到了一个关于 的不等式组:
整理得:
因此,我们只需要判断这个不等式是否成立即可,最简单的判断方法则是判断两个端点的关系是否成立:
long long needC = max(0LL, -y);long long maxC = k / 2;
if (maxC >= needC) cout << "YES\n";else cout << "NO\n";至此,这题结束
完整代码
#include <bits/stdc++.h>using namespace std;
int main() { ios::sync_with_stdio(false); cin.tie(nullptr);
int t; cin >> t; while (t--) { long long x, y; cin >> x >> y;
long long d = x - 2 * y;
if (d < 0 || d % 3 != 0) { cout << "NO\n"; continue; }
long long k = d / 3; long long needC = max(0LL, -y); long long maxC = k / 2;
if (maxC >= needC) cout << "YES\n"; else cout << "NO\n"; }
return 0;}