一道模板题,就是让你求所有的面积。
附上链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542
先上代码,实在看不懂就看我的图...
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N = 205;
int n;
double y[N];
struct Line
{
double x;
double down,up;
int flag;
}line[N];
bool cmp(Line a,Line b)
{
return a.x < b.x;
}
struct Node
{
double l,r;
double x;
int cover;
bool flag;
}node[N << 2];
void build(int l,int r,int i)
{
node[i].l = y[l];
node[i].r = y[r];
node[i].x = -1;
node[i].flag= false;
node[i].cover = 0;
if(l+1 == r)
{
node[i].flag = true;
return ;
}
int mid =(l + r)/2;
build(l,mid,i*2);//这里为什么是mid,是因为线段连续呀...第一个坑
build(mid,r,i*2+1);
}
double Insert_query(int i,double x,double l,double r, int flag)
{
if(l >= node[i].r || r <= node[i].l) //不重合
{
return 0;
}
if(node[i].flag)
{
if(node[i].cover > 0)
{
double ans = 0;
double pre = node[i].x;
ans = (x-pre)*(node[i].r - node[i].l);
node[i].x = x;//平移
node[i].cover += flag;//改变覆盖边数
return ans;
}
else
{
node[i].cover += flag;
node[i].x = x;
return 0;
}
}
double ans1,ans2;
ans1 = Insert_query(i*2,x,l,r,flag);
ans2 = Insert_query(i*2+1,x,l,r,flag);
return ans1+ans2;
}
int main()
{
int n;
int t = 1;
while(cin >> n)
{
int cnt =0;
if(n == 0)
break;
while(n--)
{
double x1,y1,x2,y2;
cin >> x1 >> y1 >> x2 >> y2;
y[cnt]=y1;
line[cnt].x=x1;
line[cnt].down=y1;
line[cnt].up=y2;
line[cnt++].flag=1; // 表示左边线段;
y[cnt]=y2;
line[cnt].x=x2;
line[cnt].down=y1;
line[cnt].up=y2;
line[cnt].flag=-1;//表示右边线段
}
sort(y,y+cnt+1);//线段树的上下界必须排序
sort(line,line+cnt+1,cmp);//排序,让线段从左往右依次加入
build(0,cnt,1);
double area = 0;
for(int i = 0;i <= cnt ;i++)//几条边就有几条查询更新操作
{
area += Insert_query(1,line[i].x,line[i].down,line[i].up,line[i].flag);
}
printf("Test case #%d\n",t++);
printf("Total explored area: %.2f\n",area);
cout << endl;//格式 wa了好几发
}
}