1. 程式人生 > >hdu3265一種錯誤的做法

hdu3265一種錯誤的做法

遇到 gif alt n! hide roo opera color 我沒

題目鏈接

這是求面積並的題目,剛開始我的思路是將挖去的矩形的入邊和出邊覆蓋效果顛倒,

即入邊-1,出邊+1,後來調試到爆炸,發現這是錯誤的做法。。原因就是對最簡單

的面積並問題沒有搞清楚。剛開始接觸掃描線的時候我就有一個問題,為什麽覆蓋

次數不需要向子區間傳遞,但是我沒有仔細去想這個問題,直到遇到這道題目。在

求相交矩形面積並的過程中,所有的線段都是成對出現,重點在於所有線段的覆蓋

都是整段整段的操作,所以不需要向下傳。而這道題目用這種做法就會出現一個區

間被較小的區間釋放的情況,所以會出錯。

技術分享圖片
#include<cstdio>
#include<algorithm>
using
namespace std; const int maxn=310;//最多矩形個數 struct edge{ int x1,x2,y; int f;//1表示入,-1表示出 edge(){} edge(int _x1,int _x2,int _y,int _f){ x1=_x1,x2=_x2,y=_y,f=_f; } bool operator <(edge &e){ if(y!=e.y) return y<e.y; return f>e.f; } };
int nVx; int Vx[maxn*4]; int nSgs; edge Sgs[maxn*4]; int num[maxn*4*4]; int len[maxn*4*4]; void build(int root,int l,int r) { num[root]=len[root]=0; if(l==r)return; int mid=(l+r)/2; build(root*2,l,mid); build(root*2+1,mid+1,r); } void pushUp(int root,int l,int r) { if(num[root]!=0
)len[root]=Vx[r+1]-Vx[l]; else if(l==r)len[root]=0; else len[root]=len[root*2]+len[root*2+1]; printf("%d %d num[%d]=%d\n",l,r,root,num[root]); } void update(int root,int L,int R,int f,int l,int r) { //printf("%d %d %d %d %d %d\n",root,L,R,f,l,r); if(L<=l&&r<=R){ num[root]+=f; pushUp(root,l,r); return ; } int mid=(l+r)/2; if(L<=mid)update(root*2,L,R,f,l,mid); if(mid<R)update(root*2+1,L,R,f,mid+1,r); pushUp(root,l,r); } int bin(int k) { int l=0,r=nVx-1,mid; while(l<=r){ mid=(l+r)/2; if(Vx[mid]==k)return mid; else if(Vx[mid]>k)r=mid-1; else l=mid+1; } return -1; } int myUnique(int a[],int n) { int sz=1; for(int i=1;i<n;i++){ if(a[i]!=a[i-1])a[sz++]=a[i]; } return sz; } int main() { freopen("in.txt","r",stdin); int N; while(scanf("%d",&N)!=EOF&&N!=0){ nVx=0; nSgs=0; for(int i=0;i<N;i++){ int x1,y1,x2,y2,x3,y3,x4,y4; scanf("%d%d%d%d%d%d%d%d", &x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4); printf("%d %d %d %d %d %d %d %d\n", x1,y1,x2,y2,x3,y3,x4,y4); Vx[nVx++]=x1,Vx[nVx++]=x2,Vx[nVx++]=x3,Vx[nVx++]=x4; Sgs[nSgs++]=edge(x1,x2,y1,1); Sgs[nSgs++]=edge(x1,x2,y2,-1); Sgs[nSgs++]=edge(x3,x4,y3,-1); Sgs[nSgs++]=edge(x3,x4,y4,1); } sort(Vx,Vx+nVx); nVx=myUnique(Vx,nVx); sort(Sgs,Sgs+nSgs); build(1,0,nVx-1); int area=0; for(int i=0;i<nSgs-1;i++){ int l=bin(Sgs[i].x1); int r=bin(Sgs[i].x2)-1; update(1,l,r,Sgs[i].f,0,nVx-1); printf("%d %d\n",len[1],Sgs[i+1].y-Sgs[i].y); area+=len[1]*(Sgs[i+1].y-Sgs[i].y); } printf("%d\n",area); } while(1); }
View Code

先貼一下思路:海報一張可以切割成4個矩形,然後就是普通的矩形面積並了,利

用線段樹維護即可

hdu3265一種錯誤的做法