您的位置:首页 > 其它

POJ 1151

2014-04-30 18:36 387 查看
思路:首先将横坐标离散化,再对纵坐标排序,然后根据y轴从下往上扫描,每次的高度就是seg[i].y-seg[i-1].y,这就相当于分矩形的宽,然后要做的事就是查询x轴(矩形长)的有效长度,这就要交给线段树了。

/*************************************************************************
> File Name:        area.cpp
> Author:         wangzhili
> Mail:           wangstdio.h@gmail.com
> Created Time:   2014/3/1 星期六 16:06:57
************************************************************************/

#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAX 1000
using namespace std;
class TreeNode
{
public:
int left;
int right;
int mid;
int cover;
int flag;
double length;
};
typedef struct
{
double xl, xr, y;
int flag;
}Line;
TreeNode node[3*MAX];
Line seg[MAX];
double x[MAX];
double length;
bool cmp(Line a, Line b)
{
return a.y < b.y;
}

void BuildTree(int k, int l, int r)
{
node[k].left = l;
node[k].right = r;
node[k].mid = (l + r) >> 1;
node[k].cover = 0;
node[k].flag = 0;
if(l + 1 == r)
{
node[k].flag = 1;
return ;
}
int mid = (l + r) >> 1;
BuildTree(k << 1, l, mid);
BuildTree(k << 1|1, mid, r);
}

void UpdateTree(int k, int l, int r, int flag)
{
if(node[k].left == l && node[k].right == r)
{
node[k].cover += flag;
node[k].length = x[r-1] - x[l-1];
return ;
}
if(node[k].flag)
return ;
if(node[k].mid <= l)
UpdateTree(k << 1|1, l, r, flag);
else if(node[k].mid >= r)
UpdateTree(k << 1, l, r, flag);
else
{
UpdateTree(k << 1, l, node[k].mid, flag);
UpdateTree(k << 1|1, node[k].mid, r, flag);
}
}

void GetLength(int k)
{
if(node[k].cover > 0)
{
length += node[k].length;
return ;
}
if(node[k].flag)
return;
GetLength(k << 1);
GetLength(k << 1|1);
}

int GetIndex(double num, int length)
{
int l, r, mid;
l = 0, r = length-1;
while(l <= r)
{
mid = (l + r) >> 1;
if(x[mid] == num)
return mid;
else if(x[mid] > num)
r = mid - 1;
else
l = mid + 1;
}
}

int main(int argc, char const *argv[])
{
int n, i, j, k, cnt;
int xl, xr;
double ans;
double x1, y1, x2, y2;
cnt = 0;
BuildTree(1, 1, 205);
// freopen("in.c", "r", stdin);
while(~scanf("%d", &n) && n)
{
j = 0;
ans = 0.;
for(i = 1; i < 408; i ++)
{
node[i].cover = 0;
}
for(i = 0; i < n; i ++)
{
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
seg[j].xl = x1;
seg[j].xr = x2;
seg[j].y = y1;
x[j] = x1;
seg[j ++].flag = 1;
seg[j].xl = x1;
seg[j].xr = x2;
seg[j].y = y2;
x[j] = x2;
seg[j ++].flag = -1;
}
sort(x, x+j);
sort(seg, seg+j, cmp);
k = 1;
for(i = 1; i < j; i ++)
{
if(x[i] != x[i-1])
x[k ++] = x[i];
}
xl = GetIndex(seg[0].xl, k) + 1;
xr = GetIndex(seg[0].xr, k) + 1;
UpdateTree(1, xl, xr, seg[0].flag);
length = 0;
GetLength(1);
for(i = 1; i < j; i ++)
{
ans += (seg[i].y-seg[i-1].y)*length;
xl = GetIndex(seg[i].xl, k)+1;
xr = GetIndex(seg[i].xr, k)+1;
UpdateTree(1, xl, xr, seg[i].flag);
length = 0.;
GetLength(1);
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n", ++cnt, ans);
}
return 0;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: