PAT顶级(几何模拟)——1011 Cut Rectangles (35 分)

1011 Cut Rectangles (35 分)


解题思路:

虽然题目给的多边形最多有10个点,但是不难得出实际上就五种情况:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
其中除了第一种没有斜边,直接考虑2个矩形能不能拼接,后面四种都是有斜边的,思路大致如下:

  1. 找到斜边的两个点,比较斜边是否斜率相等、长度相同(通过▲x,▲y入手,注意会翻转)
  2. 比较各个情况的对边能否相等,如三角形+梯形,则是梯形斜边两个点所在的两条线x1,x2,min(x1,x2)+三角形的任一直角边=max(x1,x2)即是可以拼接

我就没见过代码比我还长的,又臭又长的垃圾

代码:

#include<bits/stdc++.h>
#include<unordered_map>
#include<unordered_set>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define mp make_pair
#define pb push_back
#define G 6.67430*1e-11
#define  rd read()
#define pi 3.1415926535
using namespace std;
const ll mod = 1e9 + 7;
const int MAXN = 30000005;
const int MAX2 = 300005;
inline ll read() {
    ll x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch>'9') {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}
pii a[10], b[10];
signed main()
{
    int n = rd;
    for (int i = 0; i < n; i++)
    {
        int x = rd;
        for (int i = 0; i < x; i++)
        {
            a[i].first = rd;
            a[i].second = rd;
        }
        int  y = rd;
        for (int i = 0; i < y; i++)
        {
            b[i].first = rd;
            b[i].second = rd;
        }

        int ans = 1;
        if (x + y > 8 || x + y < 6)ans = 0;
        vector<int> va, vb;
        //找斜边
        for (int i = 0; i < x; i++)
        {
            int t = 0;
            for (int j = 0; j < x; j++)
            {
                if (i != j && (a[i].first == a[j].first || a[i].second == a[j].second))
                {
                    t++;
                }
            }
            if (t <= 1)
            {
                va.push_back(i);
            }
        }
        for (int i = 0; i < y; i++)
        {
            int t = 0;
            for (int j = 0; j < y; j++)
            {
                if (i != j && (b[i].first == b[j].first || b[i].second == b[j].second))
                {
                    t++;
                }
            }
            if (t <= 1)
            {
                vb.push_back(i);
            }
        }
        //如果没找到
        if (va.size() == 0 && vb.size() == 0)
        {
            //两个矩形
            if (x != 4 || y != 4)ans = 0;
            int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
            //取两个矩形的边长
            for (int i = 0; i < x; i++)
            {
                for (int j = 0; j < x; j++)
                {
                    if (i != j && a[i].first == a[j].first)
                    {
                        if (x1 && x1 != abs(a[i].second - a[j].second))ans = 0;
                        x1 = abs(a[i].second - a[j].second);
                    }
                    if (i != j && a[i].second == a[j].second)
                    {
                        if (x2 && x2 != abs(a[i].first - a[j].first))ans = 0;
                        x2 = abs(a[i].first - a[j].first);
                    }
                }
            }
            for (int i = 0; i < y; i++)
            {
                for (int j = 0; j < y; j++)
                {
                    if (i != j && b[i].first == b[j].first)
                    {
                        if (y1 && y1 != abs(b[i].second - b[j].second))ans = 0;
                        y1 = abs(b[i].second - b[j].second);
                    }
                    if (i != j && b[i].second == b[j].second)
                    {
                        if (y2 && y2 != abs(b[i].first - b[j].first))ans = 0;
                        y2 = abs(b[i].first - b[j].first);
                    }
                }
            }
            //判断是否相等
            if (!y1 || !y2 || !x1 || !x2)ans = 0;
            if (x1 != y1 && x1 != y2 && x2 != y1 && x2 != y2)ans = 0;
        }
        else if (va.size() == 2 && vb.size() == 2)
        {
            //两个梯形、三角形或者一个三角形一个五边形、梯形,比较斜边长度、斜率(▲x1,▲x2,▲y1,▲y2)以及边是否相加为另一边长
            int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
            for (int i = 0; i < x; i++)
            {

                if ((i != va[0]) && (a[i].first == a[va[0]].first || a[i].second == a[va[0]].second))
                {
                    x1 = max(abs(a[i].first - a[va[0]].first), abs(a[i].second - a[va[0]].second));
                }
                if ((i != va[1]) && (a[i].first == a[va[1]].first || a[i].second == a[va[1]].second))
                {
                    x2 = max(abs(a[i].first - a[va[1]].first), abs(a[i].second - a[va[1]].second));
                }
            }
            for (int i = 0; i < y; i++)
            {
                if ((i != vb[0]) && (b[i].first == b[vb[0]].first || b[i].second == b[vb[0]].second))
                {
                    y1 = max(abs(b[i].first - b[vb[0]].first), abs(b[i].second - b[vb[0]].second));
                }
                if ((i != vb[1]) && (b[i].first == b[vb[1]].first || b[i].second == b[vb[1]].second))
                {
                    y2 = max(abs(b[i].first - b[vb[1]].first), abs(b[i].second - b[vb[1]].second));
                }
            }
            map<int, int> m;
            m[abs(a[va[0]].first - a[va[1]].first)]++;
            m[abs(a[va[0]].second - a[va[1]].second)]++;
            m[abs(b[vb[0]].first - b[vb[1]].first)]++;
            m[abs(b[vb[0]].second - b[vb[1]].second)]++;
            for (auto p : m)
            {
                if (p.second < 2)ans = 0;
            }
            if (x == y)
            {
                //两个梯形、三角形,长边、短边相等 
                if (max(x1, x2) != max(y1, y2) || min(x1, x2) != min(y1, y2))ans = 0;
            }
            else if (max(x, y) == 5 && min(x, y) == 3)
            {
                int t1 = 0, t2 = 0;
                //五边形+三角形
                if (x > y)
                {
                    int pos = -1;
                    for (int i = 0; i < x; i++)
                    {
                        if (a[i].first != a[va[0]].first && a[i].second != a[va[0]].second && a[i].first != a[va[1]].first && a[i].second != a[va[1]].second)
                        {
                            pos = i;
                        }
                    }
                    for (int i = 0; i < x; i++)
                    {
                        if (i != pos && a[pos].first == a[i].first)
                        {
                            t1 = abs(a[pos].second - a[i].second);
                        }
                        if (i != pos && a[pos].second == a[i].second)
                        {
                            t2 = abs(a[pos].first - a[i].first);
                        }
                    }
                }
                else
                {
                    int pos = -1;
                    for (int i = 0; i < y; i++)
                    {
                        if (b[i].first != b[vb[0]].first && b[i].second != b[vb[0]].second && b[i].first != b[vb[1]].first && b[i].second != b[vb[1]].second)
                        {
                            pos = i;
                        }
                    }
                    for (int i = 0; i < y; i++)
                    {
                        if (i != pos && b[pos].first == b[i].first)
                        {
                            t1 = abs(b[pos].second - b[i].second);
                        }
                        if (i != pos && b[pos].second == b[i].second)
                        {
                            t2 = abs(b[pos].first - b[i].first);
                        }
                    }
                }
                //判断相加是否等于另一边
                if (!((max(x1 + y1, x2 + y2) == max(t1, t2) && min(x1 + y1, x2 + y2) == min(t1, t2)) || (max(x1 + y2, x2 + y1) == max(t1, t2) && min(x1 + y2, x2 + y1) == min(t1, t2))))ans = 0;
            }
            else if (max(x, y) == 4 && min(x, y) == 3)
            {
                int t1 = 0, t2 = 0, t3 = 0;
                //梯形+三角形
                if (x > y)
                {
                    //if (!(min(x1, x2) + y1 == max(x1, x2) || min(x1, x2) + y2 == max(x1, x2)))ans = 0;
                }
                else
                {
                    //if (!(min(y1, y2) + x1 == max(y1, y2) || min(y1, y2) + x2 == max(y1, y2)))ans = 0;
                }
            }
            else ans = 0;
        }
        else ans = 0;
        cout << (ans ? "YES" : "NO");
        if (i != n - 1)cout << endl;
    }
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值