1011 Cut Rectangles (35 分)
解题思路:
虽然题目给的多边形最多有10个点,但是不难得出实际上就五种情况:
其中除了第一种没有斜边,直接考虑2个矩形能不能拼接,后面四种都是有斜边的,思路大致如下:
- 找到斜边的两个点,比较斜边是否斜率相等、长度相同(通过▲x,▲y入手,注意会翻转)
- 比较各个情况的对边能否相等,如三角形+梯形,则是梯形斜边两个点所在的两条线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;
}