这次用了矩形分割的方法实现了下,参考了这的代码,用了上浮+矩形分割的思想,个人觉得递归的写法更形象,且方便,于是,看了04年薛矛大牛论文后,实现了这个方法,觉得很赞,先从X方向上割掉,再割掉Y方向上。不过最糟糕复杂度是O(N^3),这个还是很可怕的,但一般是达不到的,这里的11个数据,都在0.1s以下,这种方法是解决一类统计类问题的利器~
下面是薛大牛论文中的伪码:
下面是用矩形分割实现该题的代码:
/*
ID: litstrong
PROG: rect1
LANG: C++
*/
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <math.h>
#include <queue>
#include <algorithm>
#include <string.h>
#include <stdio.h>
using namespace std;
const int MAXN = 10005;
const int MAXC = 2505;
int c_ans[MAXC];
int A, B, N;
class CRECT
{
public:
int nx, mx, ny, my, c;
public:
CRECT() {}
CRECT(int _nx, int _mx, int _ny, int _my, int _c) :
nx(_nx), mx(_mx), ny(_ny), my(_my), c(_c) {}
}rect[MAXN];
void CutFloat(int level, int x1, int y1, int x2, int y2, int c)
{
if(level > N)
{
c_ans[c] += (x2 - x1) * (y2 - y1);
return;
}
int x3 = rect[level].nx, y3 = rect[level].ny;
int x4 = rect[level].mx, y4 = rect[level].my;
if(x3 >= x2 || x4 <= x1 || y3 >= y2 || y4 <= y1)
CutFloat(level + 1, x1, y1, x2, y2, c);
else
{
int k1, k2, k3, k4;
//x
k1 = max(x1, x3); k2 = min(x2, x4);
if(x1 < k1) CutFloat(level + 1, x1, y1, k1, y2, c);
if(k2 < x2) CutFloat(level + 1, k2, y1, x2, y2, c);
//y
k3 = max(y1, y3); k4 = min(y2, y4);
if(y1 < k3) CutFloat(level + 1, k1, y1, k2, k3, c);
if(k4 < y2) CutFloat(level + 1, k1, k4, k2, y2, c);
}
}
int main()
{
freopen("rect1.in", "r", stdin);
freopen("rect1.out", "w", stdout);
scanf("%d%d%d", &A, &B, &N);
rect[0] = CRECT(0, A, 0, B, 1);
for(int i = 1; i <= N; i++)
{
int nx, mx, ny, my, c;
scanf("%d%d%d%d%d", &nx, &ny, &mx, &my, &c);
rect[i] = CRECT(min(nx, mx), max(nx, mx), min(ny, my), max(ny, my), c);
}
memset(c_ans, 0, sizeof(c_ans));
//上浮
for(int i = N; i >= 0; i--)
{
CutFloat(i + 1, rect[i].nx, rect[i].ny, rect[i].mx, rect[i].my, rect[i].c);
}
for(int i = 0; i < MAXC; i++)
if(c_ans[i]) printf("%d %d\n", i, c_ans[i]);
}