原题链接: http://acm.hdu.edu.cn/showproblem.php?pid=1542
题意:
给定n个矩形,n行数据,每行四个,代表矩形的左下角,右上角坐标,问矩形的总面积。就是求矩形并面积。
思路:
以横坐标个数为区间建线段树,定义一个结构体做扫描线。
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string.h>
using namespace std;
struct Line
{
double l, r, h;
int flag;
bool operator<(Line & a) const
{
return h < a.h;
}
}line[405 * 4];
int n;
int cover[405 * 4];//覆盖的次数
double X[405 * 4];//保存所有横坐标
double sum[405];//底边长
/* 二分搜索 */
int BS(double x)
{
int l = -1;
int r = n;
int mid;
while (1)
{
mid = (l + r) / 2;
if (X[mid] == x)
return mid;
else if (X[mid] < x)
l = mid;
else
r = mid;
if (r - l == 1)
return r;
}
return -1;
}
void update(int pos, int flag, int l, int r, int root)
{
if (l == r)
{
cover[pos] += flag;
if (cover[pos])
sum[root] = X[pos + 1] - X[pos];
if (!cover[pos])
sum[root] = 0;
return;
}
int mid = (l + r) / 2;
if (pos <= mid)
update(pos, flag, l, mid, root * 2);
else
update(pos, flag, mid + 1, r, root * 2 + 1);
sum[root] = sum[root * 2] + sum[root * 2 + 1];
}
int main()
{
int num;
int T = 1;
double ans;
double x1, y1, x2, y2;
while (~scanf("%d", &n) && n)
{
num = 1;
int t = 1;
for (int i = 0; i < n; i++)
{
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
line[t].h = y1;
line[t].l = x1;
line[t].r = x2;
line[t++].flag = 1;
line[t].h = y2;
line[t].l = x1;
line[t].r = x2;
line[t++].flag = -1;
X[num++] = x1;
X[num++] = x2;
}
n = t;
sort(X + 1, X + num);
sort(line + 1, line + n);
memset(sum, 0, sizeof(sum));
memset(cover, 0, sizeof(cover));
ans = 0.0;
for (int i = 1; i <= n; i++)
{
ans += sum[1] * (line[i].h - line[i - 1].h);
int l = BS(line[i].l);
int r = BS(line[i].r) - 1;
for (int j = l; j <= r; j++)
update(j, line[i].flag, 1, n, 1);
}
printf("Test case #%d\nTotal explored area: %.2f\n\n", T++, ans);
}
return 0;
}