POJ1151-Atlantis【线段树,扫描线,离散化】
生活随笔
收集整理的這篇文章主要介紹了
POJ1151-Atlantis【线段树,扫描线,离散化】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目鏈接:http://poj.org/problem?id=1151
題目大意
有n個矩形,求所以矩形的覆蓋面積。
解題思路
我們用離散化一個坐標,然后每次用線段樹維護這個寬度內覆蓋高度和,然后定義左上的點是加入,右下的點是彈出。
code
#include<cstdio> #include<algorithm> #include<cstring> #define N 110 using namespace std; struct treenode{int l,r;double mark,val; }t[N*8]; struct node{double x1,x2,y;int flag; }a[N*2]; int n,tot,l; double x[N*2],ans; void build(int k,int l,int r) {t[k].l=l;t[k].r=r;if(l==r) return;int mid=(l+r)>>1;build(k*2,l,mid);build(k*2+1,mid+1,r); } void change(int k,int l,int r,int num) {if(t[k].l==l&&t[k].r==r){t[k].mark+=num;//標記了多少次if(t[k].mark)t[k].val=x[t[k].r+1]-x[t[k].l];//如果標記就直接返回答案else if(l==r) t[k].val=0;else t[k].val=t[k*2].val+t[k*2+1].val;//合并下面return;}int mid=(t[k].l+t[k].r)>>1;if(r<=mid) change(k*2,l,r,num);else if(l>mid) change(k*2+1,l,r,num);else change(k*2,l,mid,num),change(k*2+1,mid+1,r,num);if(t[k].mark)t[k].val=x[t[k].r+1]-x[t[k].l];else t[k].val=t[k*2].val+t[k*2+1].val; } bool cmp(node x,node y) {return x.y<y.y;} int main() {while(scanf("%d",&n)&&n){memset(t,0,sizeof(t));ans=0;int cnt=0,l=0;double x1,y1,x2,y2;for(int i=1;i<=n;i++){scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);x[++l]=x1;x[++l]=x2;a[++cnt]=(node){x1,x2,y1,1};a[++cnt]=(node){x1,x2,y2,-1};}stable_sort(x+1,x+l+1);l=unique(x+1,x+l+1)-(x+1);//離散化build(1,1,l);//建樹stable_sort(a+1,a+1+cnt,cmp);for(int i=1;i<cnt;i++){int xx=lower_bound(x+1,x+l,a[i].x1)-x;int yy=lower_bound(x+1,x+l,a[i].x2)-x-1;//找到位置change(1,xx,yy,a[i].flag);//修改ans+=t[1].val*(a[i+1].y-a[i].y);//計算該寬度答案}printf("Test case #%d\nTotal explored area: %.2f\n\n",++tot,ans);} }總結
以上是生活随笔為你收集整理的POJ1151-Atlantis【线段树,扫描线,离散化】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 被人忽略的ADC被人忽略的说说
- 下一篇: POJ2482-Stars in You