2019杭电多校赛第八场的09
存在两三种做法
最简单的也是最暴力的应该就是 讨论所有情况
比赛的时候其实已经把所有情况都列出来了
但是实现的时候又变得混乱了(我就没写emm)
这时候 川酱 提出了一种思路就是
先离散化两个矩形的坐标
然后 求图中的连通块数目
代码如下:
#include <stdio.h>
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int vis[100][100];
int nx[4] = {1, 0, -1, 0};
int ny[4] = {0, 1, 0, -1};
int x[10], y[10], xx[10], yy[10];
int tmp;
void dfs(int a, int b)
{
vis[a][b] = 2;
for (int i = 0; i < 4; i++) {
int newx = a + nx[i];
int newy = b + ny[i];
if (vis[newx][newy] == 0 && newx < 10 && newx >= 0 && newy < 10 && newy >= 0) {
dfs(newx, newy);
}
}
}
int main()
{
int t;
scanf("%d", &t);
while (t--) {
memset(vis, 0, sizeof vis);
tmp = 0;
for (int i = 0; i < 4; i++) {
scanf("%d%d", &x[i], &y[i]);
xx[i] = x[i];
yy[i] = y[i];
}
//离散化二维坐标
sort(xx, xx + 4);
sort(yy, yy + 4);
int len1 = unique(xx, xx + 4) - xx;
int len2 = unique(yy, yy + 4) - yy;
for (int i = 0; i < 4; i++) {
x[i] = lower_bound(xx, xx + 4, x[i]) - xx;
x[i] = x[i] * 2 + 1;
y[i] = lower_bound(yy, yy + 4, y[i]) - yy;
y[i] = y[i] * 2 + 1;
}
//将矩形边框标记出来
for (int i = x[0]; i <= x[1]; i++) {
vis[i][y[0]] = 1;
vis[i][y[1]] = 1;
}
for (int i = y[0]; i <= y[1]; i++) {
vis[x[0]][i] = 1;
vis[x[1]][i] = 1;
}
for (int i = x[2]; i <= x[3]; i++) {
vis[i][y[2]] = 1;
vis[i][y[3]] = 1;
}
for (int i = y[2]; i <= y[3]; i++) {
vis[x[2]][i] = 1;
vis[x[3]][i] = 1;
}
// for (int i = 0; i < 10; i++)
// {
// for (int j = 0; j < 10; j++) {
// printf("%d ", vis[i][j]);
// }
// printf("\n");
// }
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++) {
if (vis[i][j] == 0) {
tmp++;
dfs(i, j);
}
}
printf("%d\n", tmp);
}
return 0;
}
当然 还有另一种神奇的方法
就是 zkx 说的求出两个矩形相交的矩形位置
然后判断这个矩形在原矩形的位置
我稍微写了一下思想就不在 另一个博客里改了
代码如下:
#include <stdio.h>
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
struct Rect {
int startX, endX, startY, endY;
};
Rect RectH(Rect r1, Rect r2)
{
Rect m;
m.startX = r1.startX < r2.startX ? r1.startX : r2.startX;
m.endX = r1.endX > r2.endX ? r1.endX : r2.endX;
m.startY = r1.startY < r2.startY ? r1.startY : r2.startY;
m.endY = r1.endY > r2.endY ? r1.endY : r2.endY;
return m;
}
Rect RectArea(Rect r1, Rect r2)
{
Rect mm = RectH(r1, r2);
Rect both ;
both.startX = r1.startX == mm.startX ? r2.startX : r1.startX;
both.endX = r1.endX == mm.endX ? r2.endX : r1.endX;
both.startY = r1.startY == mm.startY ? r2.startY : r1.startY;
both.endY = r1.endY == mm.endY ? r2.endY : r1.endY;
return both;
}
int run(Rect r1, Rect r2)
{
if (r1.startX != r2.startX || r1.endX != r2.endX || r1.endY != r2.endY || r1.startY != r2.startY) {
return 0;
} else {
return 1;
}
}
int cmp(Rect r1, Rect r2)
{
if (run(r1, r2) == 1) {
return 1;
}
int lenx1 = r1.endX - r1.startX;
int lenx2 = r2.endX - r2.startX;
if (lenx1 == lenx2) {
if (r1.startY == r2.startY || r1.endY == r2.endY) {
return 2;
} else {
return 3;
}
} else {
int leny1 = r1.endY - r1.startY;
int leny2 = r2.endY - r2.startY;
if (leny1 == leny2)
if (r1.startX == r2.startX || r1.endX == r2.endX) {
return 2;
} else {
return 3;
}
else {
return 2;
}
}
}
int main()
{
int t;
scanf("%d", &t);
while (t--) {
Rect r1, r2;
scanf("%d%d%d%d", &r1.startX, &r1.startY, &r1.endX, &r1.endY);
scanf("%d%d%d%d", &r2.startX, &r2.startY, &r2.endX, &r2.endY);
Rect m = RectArea(r1, r2);
// printf("%d %d %d %d ***\n", m.startX, m.startY, m.endX, m.endY);
if (m.startX >= m.endX || m.startY >= m.endY) {
printf("3\n");
continue;
}
if (run(r1, r2) == 1) {
printf("2\n");
continue;
}
// printf("%d %d ", cmp(m, r1), cmp(m, r2));
int ans = cmp(m, r1) + cmp(m, r2);
printf("%d\n", ans);
}
return 0;
}
最后 膜拜一下两位大佬
有机会一定加友链!!!