比较基础的矩形切割,是POJ 2528 Mayor’s posters的二维版。
还是要注意边缘的情况,比如当(0,8)(18,18) 切割(18,0)(19,19)的时候,结果应该是得到三个矩形
- (18,19)(18,19) --> 面积为1
- (19,0)(19,19) --> 面积为20
- (18,0)(18,7) --> 面积为8
恩,其实我一直没搞懂为啥给数据的时候llx和lly是真正的坐标值,而urx和ury却必须减一之后再用…
#include<iostream>
#include<stack>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<cmath>
using namespace std;
const int M = 100000;
const int N = 1000;
struct rect
{
int llx, lly;
int urx, ury;
int color;
rect(int lx = 0, int ly = 0, int rx = 0, int ry = 0, int c = 0)
: llx(lx), lly(ly), urx(rx), ury(ry), color(c) {}
int S()
{
return (urx - llx + 1) * (ury - lly + 1);
}
}rects[M], cur;
int tot;
inline bool cross(const rect& r1, const rect& r2)
{
return !(
(r1.llx > r2.urx)
|| (r1.urx < r2.llx)
|| (r1.lly > r2.ury)
|| (r1.ury < r2.lly));
}
inline void add(const rect& t)
{
rects[tot++] = t;
}
inline void del(int idx)
{
rects[idx] = rects[--tot];
}
void cut(const rect& t, bool vertical = false)
{
int k1, k2;
rect tem = t;
if(vertical)
{
k1 = max(t.lly, cur.lly);
k2 = min(t.ury, cur.ury);
if(t.lly < k1)
{
tem.ury = k1 - 1;
add(tem);
}
if(k2 < t.ury)
{
tem = t, tem.lly = k2 + 1;
add(tem);
}
}
else
{
k1 = max(t.llx, cur.llx);
k2 = min(t.urx, cur.urx);
if(t.llx < k1)
{
tem.urx = k1 - 1;
add(tem);
}
if(t.urx > k2)
{
tem = t, tem.llx = k2 + 1;
add(tem);
}
tem = t, tem.llx = k1 , tem.urx = k2;
cut(tem, true);
}
}
int main(int argc, char *argv[])
{
#ifdef ACM_LOCAL
freopen("in", "r", stdin);
#else
#ifndef ONLINE_JUDGE
freopen("rect1.in", "r", stdin);
freopen("rect1.out", "w", stdout);
#endif
#endif
int a, b, n;
scanf("%d %d %d", &a, &b, &n);
add(rect(0, 0, a-1, b-1, 1));
while(n--)
{
scanf("%d %d %d %d %d", &cur.llx, &cur.lly, &cur.urx, &cur.ury, &cur.color);
cur.urx--, cur.ury--;
for(int i = tot-1; i>= 0; i--)
{
if(cross(cur, rects[i]))
{
cut(rects[i]);
del(i);
}
}
add(cur);
}
map<int, int> cnt;
for(int i = 0; i!= tot; i++)
{
cnt[rects[i].color] += rects[i].S();
}
for(map<int, int>::iterator it = cnt.begin(); it!= cnt.end(); it++)
{
if(it->second)
printf("%d %d\n", it->first, it->second);
}
return 0;
}