题解 - CodeForces 1030B Vasya and Cornfield

1 minute read

Published:

题目传送门

前置知识

平面直角坐标系、一次函数及其性质(应该是八年级上学期知数学识点,没学过的请自行查询资料)、等腰三角形的三线合一、矩形的性质。

思路

首先,平面直角坐标系内有两条直线非常特殊,它们是 \(y=x\) 和 \(y=-x\),它们分别是一三象限和二四象限的角平分线。而与它们平行的线,即 \(y=x+b\) 和 \(y=-x+b\),也非常特殊。

  1. 记 \(y=x+b\) 与 X 轴交于 (m,0),与 Y 轴交于 (0,n),不难发现,\(-m=n=b\)。如图所示,\(b=1\) 的情况。
    y=x+1
  2. 同样的,记 \(y=-x+b\) 与 X 轴交于 (m,0),与 Y 轴交于 (0,n),不难发现,\(m=n=b\)。如图所示,\(b=1\) 的情况。
    y=-x+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;
}