1. 程式人生 > >坐標離散化

坐標離散化

++ eof max uniq style dfs class out make

題目鏈接:挑戰書上的例題

題意:w*h的長方形上畫了n條寬度為1的直線,求這些直線將長方形劃分為多少個區域

題解:顯然用DFS填水坑的方法做,但是w,h過大,無法開這麽大的數組,所以這裏用到了一個坐標離散化的方法

對於這個方法,我的理解就是刪掉一些沒用的區域(不會對結果產生影響)。手擼了一遍書上的代碼,因為怕dfs爆棧,所以用bfs做....

就是這樣,喵、

 1 #include <queue>
 2 #include <vector>
 3 #include <cstring>
 4 #include <iostream>
 5
#include <algorithm> 6 using namespace std; 7 8 int W,H,N; 9 const int maxn=555; 10 int X1[maxn],X2[maxn],Y1[maxn],Y2[maxn];//開始列,結束列.開始行,結束行 11 bool fld[6*maxn][6*maxn]; 12 int dx[4]={0,0,1,-1}; 13 int dy[4]={1,-1,0,0}; 14 15 //坐標離散化 16 int compress(int *x1,int *x2,int w){ 17 vector <int
> xs; 18 for(int i=0;i<N;i++){ 19 for(int d=-1;d<=1;d++){ 20 int tx1=x1[i]+d,tx2=x2[i]+d; 21 if(tx1>=1&&tx1<=w) xs.push_back(tx1); 22 if(tx2>=1&&tx2<=w) xs.push_back(tx2); 23 } 24 } 25 sort(xs.begin(),xs.end());
26 xs.erase(unique(xs.begin(),xs.end()),xs.end());//去重 27 for(int i=0;i<N;i++){//轉變成新的x1,x2 28 x1[i]=find(xs.begin(),xs.end(),x1[i])-xs.begin(); 29 x2[i]=find(xs.begin(),xs.end(),x2[i])-xs.begin(); 30 } 31 return xs.size(); 32 } 33 34 void solve(){ 35 //離散化 36 W=compress(X1,X2,W); 37 H=compress(Y1,Y2,H); 38 memset(fld,0,sizeof(fld)); 39 40 //填充網絡,交點 41 for(int i=0;i<N;i++){ 42 for(int y=Y1[i];y<=Y2[i];y++){ 43 for(int x=X1[i];x<=X2[i];x++){ 44 fld[y][x]=true; 45 } 46 } 47 } 48 49 int ans=0; 50 for(int y=0;y<H;y++){ 51 for(int x=0;x<W;x++){ 52 if(fld[y][x]) continue; 53 ans++; 54 queue < pair<int,int> > Q; 55 Q.push(make_pair(x,y)); 56 while(!Q.empty()){ 57 int sx=Q.front().first,sy=Q.front().second; 58 Q.pop(); 59 for(int i=0;i<4;i++){ 60 int tx=sx + dx[i],ty=sy + dy[i]; 61 if(tx<0 || tx>=W || ty<0 || ty>=H || fld[ty][tx]) continue; 62 Q.push(make_pair(tx,ty)); 63 fld[ty][tx]=true; 64 } 65 } 66 } 67 } 68 cout<<ans<<endl; 69 } 70 71 int main(){ 72 while(cin>>W>>H>>N){ 73 for(int i=0;i<N;i++) cin>>X1[i]; 74 for(int i=0;i<N;i++) cin>>X2[i]; 75 for(int i=0;i<N;i++) cin>>Y1[i]; 76 for(int i=0;i<N;i++) cin>>Y2[i]; 77 solve(); 78 } 79 return 0; 80 }

坐標離散化