题目链接:[ HDU - 1542 ]
题目大意:给你n个矩形的左下角坐标和右上角坐标,求矩形相交的面积。
题解
扫描线 + 离散化板子
代码如下
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
double dif_x[500];
struct node
{
double x1,x2,y;
int flag;
void init(double l, double r, double h, int key) {
x1 = l; x2 = r; y = h; flag = key;
}
}line[500];
bool cmp(node a, node b)
{
return a.y < b.y;
}
struct node2
{
int l, r, cnt;
double len;
}tree[1000];
void build_tree(int id, int l, int r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].cnt = 0;
tree[id].len = 0;
if(l == r)
return;
int mid = (r + l) >> 1;
build_tree(id << 1, l, mid);
build_tree((id << 1) + 1, mid + 1, r);
}
void getlen(int id)
{
if(tree[id].cnt >= 1)
tree[id].len = dif_x[tree[id].r+1] - dif_x[tree[id].l];
else
tree[id].len = tree[id<<1].len + tree[(id<<1)|1].len;
}
void update(int id,int l,int r,int v)
{
if(tree[id].l==l && tree[id].r==r) {
tree[id].cnt += v;
getlen(id);
return;
}
int mid = (tree[id].l + tree[id].r) >> 1;
if(r <= mid)
update(id << 1,l,r,v);
else if(l > mid)
update((id << 1) + 1, l, r, v);
else {
update(id << 1, l, mid, v);
update((id << 1) + 1, mid + 1, r, v);
}
getlen(id);
}
int mySearch(double p, int l, int r)
{
while(l <= r) {
int mid = (l + r) >> 1;
if(dif_x[mid] == p)
return mid;
if(dif_x[mid] < p)
l = mid + 1;
else
r = mid - 1;
}
}
int main(void)
{
int n, noc = 0;
while (~scanf("%d", &n)) {
if (n == 0)
break;
noc++;
double x1, y1, x2, y2;
int line_num = 0;
for(int i = 0; i < n; i++) {
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
line[line_num].init(x1, x2, y1, 1);
dif_x[line_num++] = x1;
line[line_num].init(x1, x2, y2, -1);
dif_x[line_num++] = x2;
}
sort(line, line + line_num, cmp);
sort(dif_x, dif_x + line_num);
int dif_x_num = unique(dif_x, dif_x + line_num) - dif_x;
build_tree(1, 0, dif_x_num - 1);
double ans = 0;
for(int i = 0; i < line_num - 1; i++) {
int line_l = mySearch(line[i].x1, 0, dif_x_num - 1);
int line_r = mySearch(line[i].x2, 0, dif_x_num-1) - 1;
update(1, line_l, line_r, line[i].flag);
ans += tree[1].len * (line[i+1].y - line[i].y);
}
printf("Test case #%d\n", noc);
printf("Total explored area: %.2lf\n\n", ans);
}
return 0;
}