日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hdu3265一种错误的做法

發布時間:2025/3/15 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu3265一种错误的做法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接

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

即入邊-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個矩形,然后就是普通的矩形面積并了,利

用線段樹維護即可

正確做法

#include<cstdio> #include<algorithm> using namespace std; const int maxn=50310;//最多矩形個數 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 nSgs; edge Sgs[maxn*8]; int num[maxn*8]; int len[maxn*8]; 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]=r-l+1;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 main() {//freopen("in.txt","r",stdin);int N;while(scanf("%d",&N)!=EOF&&N!=0){nSgs=0;int lb=0,rb=maxn;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);Sgs[nSgs++]=edge(x1,x2,y1,1);Sgs[nSgs++]=edge(x1,x2,y3,-1);Sgs[nSgs++]=edge(x1,x3,y3,1);Sgs[nSgs++]=edge(x1,x3,y4,-1);Sgs[nSgs++]=edge(x4,x2,y3,1);Sgs[nSgs++]=edge(x4,x2,y4,-1);Sgs[nSgs++]=edge(x1,x2,y4,1);Sgs[nSgs++]=edge(x1,x2,y2,-1);lb=min(x1,lb);rb=max(x2,rb);}sort(Sgs,Sgs+nSgs);build(1,lb,rb);long long area=0;for(int i=0;i<nSgs-1;i++){int l=Sgs[i].x1;int r=Sgs[i].x2-1;if(l<=r)update(1,l,r,Sgs[i].f,lb,rb-1);//printf("%d %d\n",len[1],Sgs[i+1].y-Sgs[i].y);area+=(long long)len[1]*(Sgs[i+1].y-Sgs[i].y);}printf("%lld\n",area);}//while(1); } View Code

參考資料

http://www.cnblogs.com/--ZHIYUAN/p/6404732.html

轉載于:https://www.cnblogs.com/MalcolmMeng/p/8456040.html

總結

以上是生活随笔為你收集整理的hdu3265一种错误的做法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。