1. 程式人生 > >hdu4052矩形面積並

hdu4052矩形面積並

建模需要注意下細節,,這是做掃描線的慣例,就是最好把模型建立在笛卡爾座標系上

剩下的看連結和註釋https://blog.csdn.net/shiqi_614/article/details/7983508

/*
掃描線解一個被覆蓋了一些面積的區間 
問能空餘地方能放置多少個1*M或M*1的矩形
設[i,j]為可以作為矩形放置起點的方塊,那麼只要統計出不能作為起點的方塊的面積即可
本題用的是點的行列號,轉換成笛卡爾座標系上的座標即可
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include
<map> #define ll long long #define maxn 100005 #define lson l,m,rt<<1 #define rson m,r,rt<<1|1 using namespace std; struct Seg{ int x,y1,y2,c; Seg(){} Seg(int a,int b,int c,int d):x(a),y1(b),y2(c),c(d){} bool operator<(const Seg & a){return x<a.x;} }segs[maxn]; map
<int,int>mp; int y[maxn],data[maxn][4],tot,toty; int sum[maxn<<2],flag[maxn<<2]; void pushup(int rt,int l,int r){ if(flag[rt]>0) sum[rt]=y[r]-y[l]; else { if(l+1==r) sum[rt]=0; else sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } } void update(int
L,int R,int c,int l,int r,int rt){ if(L<=l && R>=r){ flag[rt]+=c; pushup(rt,l,r); return; } int m=l+r>>1; if(L<m) update(L,R,c,lson); if(R>m) update(L,R,c,rson); pushup(rt,l,r); } ll solve(int n,int w,int h,int m){ memset(y,0,sizeof y); memset(segs,0,sizeof segs); memset(sum,0,sizeof sum); memset(flag,0,sizeof flag); mp.clear(); tot=toty=0; y[toty++]=1,y[toty++]=h; segs[tot++]=Seg(max(1,w-m),1,h,1); segs[tot++]=Seg(w,1,h,-1); for(int i=0;i<n;i++){ int x1=max(1,data[i][0]-m),y1=data[i][1]; int x2=data[i][2],y2=data[i][3]; segs[tot++]=Seg(x1,y1,y2,1); segs[tot++]=Seg(x2,y1,y2,-1); y[toty++]=y1;y[toty++]=y2; } sort(y,y+toty); toty=unique(y,y+toty)-y; for(int i=0;i<toty;i++) mp[y[i]]=i; sort(segs,segs+tot); ll res=0; for(int i=0;i<tot;i++){ if(i!=0) res+=(ll)(segs[i].x-segs[i-1].x)*sum[1]; update(mp[segs[i].y1],mp[segs[i].y2],segs[i].c,0,toty-1,1); // cout << res<<endl; } // cout << res << endl <<endl; return res; } int main(){ int w,h,n,m; while(scanf("%d%d%d%d",&w,&h,&n,&m)==4){ for(int i=0;i<n;i++) for(int j=0;j<4;j++){ scanf("%d",&data[i][j]); if(j==2||j==3)data[i][j]++; } ll res1=(ll)(w*h)-solve(n,w+1,h+1,m-1);//把點行列號轉換成笛卡爾座標,即把點擴充套件成一塊單位面積 for(int i=0;i<n;i++){//對換矩形的xy軸座標 swap(data[i][0],data[i][1]); swap(data[i][2],data[i][3]); } ll res2=(ll)(w*h)-solve(n,h+1,w+1,m-1); //cout << res1 << " " << res2 << endl; if(m!=1) printf("%lld\n",res1+res2); else printf("%lld\n",res1);//注意這個細節 } return 0; }