White Sheet(图形)

127 阅读2分钟

Problem - C - Codeforces

原题题面

image.png

题目描述

按次序给出六个点的坐标分别为: x1,x2,y1,y2,x3,x4,y3,y4,x5,x6,y5,y6x_1,x_2,y_1,y_2,x_3,x_4,y_3,y_4,x_5,x_6,y_5,y_6。分别代表三个长方形的左下角和右上角的坐标。其中第一个长方形为白色,后两个长方形为黑色。现在将白色长方形置于最底层,问两个黑色长方形能否完全覆盖住白色长方形,黑色长方形允许有重叠。

数据格式

image.png

样例

输入样例1

2 2 4 4
1 1 3 5
3 1 5 5

输出样例1

NO

输入样例2

3 3 7 5
0 0 4 6
0 0 7 4

输出样例2

YES

题目分析

这是一道 图形 题。

现在介绍两种解题方式。

解法1 数学分析

首先我们需要计算出三个长方形的面积,记为 s,s1,s2s,s_1,s_2,分别代表白色长方形面积,一号黑色长方形面积,二号黑色长方形面积。我们要求黑色长方形是否可以覆盖白色长方形,即判断 s1s+s2ss1s2s_1\cap s + s_2\cap s - s_1\cap s_2 是否大于 ss。几何意义为判断两个黑色长方形与白色长方形的交集的并集是否大于白色正方形的面积。

解法2 比较法

相较于第一种官方解法外,还有很多种图形比较的方法,在本题的 vp 中,我是用一种图形的比较通过题目的,这也是本题代码分享的版本,第一种方法代码见官方题解。

我们先思考一件事,如果是判断一个黑色长方形如何覆盖白色长方形该如何做,答案是显然的,直接比较黑色长方形的上下左右界是否能够覆盖白色长方形的边界即可。

首先我们先提取出一个黑色长方形,将另一个黑色长方形作为最终的判断依据。现在我们思考第一个黑色长方形如何对最终判断产生贡献。如果这个黑色长方形仅是覆盖掉白色长方形的某一角或处于白色长方形之间,即无法对白色长方形产生一刀切的效果,那么这个黑色长方形的存在是无意义的,因为方形结构的特点使他留下的部分仍旧需要被覆盖。

Accept代码

#include <bits/stdc++.h>

using namespace std;

struct P
{
    int x1, y1, x2, y2;
} p[3];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    int t; t = 1;
    while (t --)
    {
        for (int i = 0; i < 3; i ++) cin >> p[i].x1 >> p[i].y1 >> p[i].x2 >> p[i].y2;
        bool flg = false;
        if (p[1].x1 <= p[0].x1 && p[1].x2 >= p[0].x2)
        {
            if (p[1].y1 <= p[0].y1) p[0].y1 = max(p[0].y1, p[1].y2);
            if (p[1].y2 >= p[0].y2) p[0].y2 = min(p[0].y2, p[1].y1);
            if (p[0].y1 >= p[0].y2) flg = true;
        }

        if (p[1].y1 <= p[0].y1 && p[1].y2 >= p[0].y2)
        {
            if (p[1].x1 <= p[0].x1) p[0].x1 = max(p[0].x1, p[1].x2);
            if (p[1].x2 >= p[0].x2) p[0].x2 = min(p[0].x2, p[1].x1);
            if (p[0].x1 >= p[0].x2) flg = true;
        }

        if (!flg && p[2].x1 <= p[0].x1 && p[2].y1 <= p[0].y1 && p[2].x2 >= p[0].x2 && p[2].y2 >= p[0].y2) flg = true;
        cout << (flg ? "NO" : "YES");
    }
    return 0;
}