方法1:浮漂法。
题目意思是,后来的覆盖在前面的上面。
我们可以倒过来, 从后往前。 这样后来的在上面,前面的,从下往上“浮“。
要点1: 2个矩形如何判断不相交?
一个矩形的最右边,在另外一个矩形最左边。 上下同理。 (程序实现的时候,因为不知道左右上下关系,所以要4个or来判断)
要点2:如何切割:
红色的在上面,白色的想上浮。 可以先让1的部分上浮。 上浮后, 矩形变小。(把上浮的地方切掉)
切割后,只有黑色的矩形这一块, 然后再让2的地方上浮。
要点3: 如何知道要切割的地方?
根据2个矩形的最左边,最右边的坐标关系。 如果【上面】的矩形,的最下面的y1坐标,在【下面】的矩形最上面的y2坐标的”下面“(y1<y2) 那么这一块就要切割(最好画图画一下)
Executing... Test 1: TEST OK [0.008 secs, 3424 KB] Test 2: TEST OK [0.011 secs, 3424 KB] Test 3: TEST OK [0.008 secs, 3424 KB] Test 4: TEST OK [0.005 secs, 3424 KB] Test 5: TEST OK [0.008 secs, 3424 KB] Test 6: TEST OK [0.008 secs, 3424 KB] Test 7: TEST OK [0.005 secs, 3424 KB] Test 8: TEST OK [0.003 secs, 3424 KB] Test 9: TEST OK [0.003 secs, 3424 KB] Test 10: TEST OK [0.003 secs, 3424 KB] Test 11: TEST OK [0.011 secs, 3424 KB] All tests OK.
/*
TASK:rect1
LANG:C++
*/
#include <iostream>
#include <cstdio>
using namespace std;
int colo[2510]={1, 0};
int zx[2510]={0},zy[2510]={0},yx[2510],yy[2510];
int output[2510]={0};
int n;
void init()
{
int ax, ay;
scanf("%d%d%d", &yx[0], &yy[0], &n);
for (int i = 1; i <= n; ++ i) scanf("%d%d%d%d%d", &zx[i], &zy[i], &yx[i], &yy[i], &colo[i]);
}
void cover(int x1, int y1, int x2, int y2, int yanse, int deep)
{
if (x1 >= x2 || y1 >= y2) return;//矩形面积为0, 显然直接退出不用做任何计算
while (deep <= n && (yx[deep] <= x1 || x2 <= zx[deep] || y2 <= zy[deep] || yy[deep]<= y1)) ++ deep;
//浮到第deep层,和第deep层的矩形进行比较,看是否有重叠地方。
//2个矩形如果没有重叠,那么情况一定是
// 一个矩形最右边,在另外一个矩形最左边的左边。 上下关系同理。
// 因为本身不知道2个矩形上下左右关系,所以分4个情况考虑,满足任何一个,就说明2个矩形没有重叠。
// 如果浮到超过deep层,就结束了
if (deep > n) //没有覆盖的
{
output[yanse] += (x2 - x1)*(y2 - y1);//当前颜色 += 当前面积
return;
}
if (x1 <= zx[deep]) //分情况分割
{
cover(x1, y1, zx[deep], y2, yanse, deep + 1);
x1 = zx[deep];
}
if (yx[deep] <= x2)
{
cover(yx[deep], y1, x2, y2, yanse, deep + 1 );
x2 = yx[deep];
}
if (y1 <= zy[deep])
{
cover(x1, y1, x2, zy[deep], yanse, deep + 1);
y1 = zy[deep];
}
if (yy[deep] <= y2)
{
cover(x1, yy[deep], x2, y2, yanse, deep + 1);
y2 = yy[deep];
}
}
void doit()
{
for (int i = n; i >= 0; -- i)
cover(zx[i],zy[i],yx[i],yy[i], colo[i],i + 1);
for (int i = 1; i <= 2500; ++ i)
if (output[i]) printf("%d %d\n",i, output[i]);
}
int main()
{
freopen("rect1.in","r",stdin);
freopen("rect1.out","w",stdout);
init();
doit();
return 0;
}