坐标离散化
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了坐标离散化相关的知识,希望对你有一定的参考价值。
题目链接:挑战书上的例题
题意: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 }
以上是关于坐标离散化的主要内容,如果未能解决你的问题,请参考以下文章