题解 - CodeForces 1030B Vasya and Cornfield
Published:
前置知识
平面直角坐标系、一次函数及其性质(应该是八年级上学期知数学识点,没学过的请自行查询资料)、等腰三角形的三线合一、矩形的性质。
思路
首先,平面直角坐标系内有两条直线非常特殊,它们是 \(y=x\) 和 \(y=-x\),它们分别是一三象限和二四象限的角平分线。而与它们平行的线,即 \(y=x+b\) 和 \(y=-x+b\),也非常特殊。
- 记 \(y=x+b\) 与 X 轴交于 (m,0),与 Y 轴交于 (0,n),不难发现,\(-m=n=b\)。如图所示,\(b=1\) 的情况。

- 同样的,记 \(y=-x+b\) 与 X 轴交于 (m,0),与 Y 轴交于 (0,n),不难发现,\(m=n=b\)。如图所示,\(b=1\) 的情况。

再反观题设中的坐标 \(A(0,d)\), \(B(d,0)\), \(C(n,n-d)\), \(D(n-d,n)\),不难发现,直线 \(AB\) 就是 \(y=-x+d\);

既然 \(AD\) 垂直于 \(AB\),那么直线 \(AD\) 的 \(k\) 值就为 1,又因为它与 Y 轴交于 \((0,d)\),所以易得它的解析式就为 \(y=x+d\)。
再看 \(BC \perp AB\),所以直线 \(BC\) 的 \(k\) 值就为 1,又因为它与 X 轴交于 \((d,0)\),由我们刚刚提到的第 1 点说到的 “\(-m=n=b\)”,在这里就可以得到该直线 \(b\) 的值为 \(-d\),所以直线 \(y=x-d\)。
最后一条直线,我们可以把它延长,与 X 轴交于 \(E\),得到这个。

因为 \(y=-x\) 是二四象限的角平分线,所以 \(\angle 1=45°\),又因为 \(y=-x+b\) 与 \(y=-x\) 互相平行,所以 \(\angle 2=45°\),易证 \(\triangle BCE\) 是等腰直角三角形。又因为 \(CF \perp BE\),所以 \(FE=FB\)。再由 \(B\)、\(C\) 的坐标求出 \(BF=n-d\),所以 \(BE=2n-2d\),易得 \(E((2n-2d)+d,0)\),即 \((2n-d,0)\)。由我们刚刚提到的第 2 点说到的 “\(m=n=b\)” 得到 \(b=2n-d\),所以直线为 \(y=-x+2n-d\)。
那么给定的一个点 \((a,b)\),只需要保证这个点在直线 \(y=-x+d\)、\(y=-x+2n-d\) 上或者上方,在直线 \(y=x-d\)、\(y=x+d\) 上或者下方,即
\[\begin{cases} b\ge -a+d\\ b\le -a+2n-d\\ b\ge a-d\\ b\le a+d \end{cases}\]就可以保证它在矩形内。
代码实现
#include <iostream>
using namespace std;
int main()
{
int d, n, m;
cin >> n >> d >> m;
for (int i = 1; i <= m; i++) {
int a, b;
cin >> a >> b;
if (b <= a + d && b >= a - d && b >= -a + d && b <= -a - d + 2 * n) {
cout << "YES" << endl;
} else {
cout << "NO" << endl;
}
}
return 0;
}
