Aizu 0513 Paint Color【离散化+BFS】
2016-08-02 17:09
387 查看
题目链接 (日语题……(:зゝ∠))
但注意,这个题是按坐标给的胶带的位置,可能坐标相邻但胶带不相邻。比如有一个胶带的x2=3,另一个胶带的x1=4,它们间显然是有空位的,但离散化后x2+1和x1相等了,在离散化过后成了相同的坐标。这个问题可以通过把每一个x2和y2都减1(因为满足x1<x2且y1<y2,减一后不会使其消失)
处理后用BFS就很方便了。但注意这题用DFS会爆栈。
题意
在直角坐标系的第一象限中有一块m*h的板子,在上面贴上了一些矩形的胶带,现在告诉每个胶带的左下坐标和右上坐标,求板子上有多少个不连通的空白区域(没有贴胶带)分析
坐标范围太大,1e6左右,直接按坐标来BFS显然不可能。但考虑到胶带数量只要1e3,可以根据胶带的位置对坐标离散化处理。离散化方法
x和y分开处理(因为互不影响)。把所有的x1,x2以及它们相邻的坐标(即x1-1,x1,x1+1)放到一个vector中,排个序并去重,再从头到尾遍历每一对x1,x2找到它们在这个vector中国的位置,得到的就是它们离散化过后的坐标。for(int i=0;i<n;++i) { for(int j=-1;j<=1;++j) { a=c1[i]+j;b=c2[i]+j; if(a>=0&&a<len) v.push_back(a); if(b>=0&&b<len) v.push_back(b); } } sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end());//去重 for(int i=0;i<n;++i) { c1[i]=lower_bound(v.begin(),v.end(),c1[i])-v.begin();//找到新坐标 c2[i]=lower_bound(v.begin(),v.end(),c2[i])-v.begin(); }
但注意,这个题是按坐标给的胶带的位置,可能坐标相邻但胶带不相邻。比如有一个胶带的x2=3,另一个胶带的x1=4,它们间显然是有空位的,但离散化后x2+1和x1相等了,在离散化过后成了相同的坐标。这个问题可以通过把每一个x2和y2都减1(因为满足x1<x2且y1<y2,减一后不会使其消失)
处理后用BFS就很方便了。但注意这题用DFS会爆栈。
AC代码
//Aizu 0531 Paint Color //AC 2016-8-2 16:53:08 //Discretization #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cctype> #include <cstdlib> #include <cstring> #include <vector> #include <set> #include <string> #include <map> #include <queue> #include <deque> #include <list> #include <sstream> #include <stack> using namespace std; #define cls(x) memset(x,0,sizeof x) #define inf(x) memset(x,0x3f,sizeof x) #define neg(x) memset(x,-1,sizeof x) #define ninf(x) memset(x,0xc0,sizeof x) #define st0(x) memset(x,false,sizeof x) #define st1(x) memset(x,true,sizeof x) #define INF 0x3f3f3f3f #define lowbit(x) x&(-x) #define bug cout<<"here"<<endl; //#define debug const int maxn=1005; int w,h; int n; int X1[1005],X2[1005],Y1[1005],Y2[1005]; int G[3*maxn][< 4000 span class="hljs-number">3*maxn]; const int dx[]={1,-1,0,0}; const int dy[]={0,0,1,-1}; void compress(int c1[],int c2[],int &len) { vector<int> v; int a,b; for(int i=0;i<n;++i) { for(int j=-1;j<=1;++j) { a=c1[i]+j;b=c2[i]+j; if(a>=0&&a<len) v.push_back(a); if(b>=0&&b<len) v.push_back(b); } } sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); for(int i=0;i<n;++i) { c1[i]=lower_bound(v.begin(),v.end(),c1[i])-v.begin(); c2[i]=lower_bound(v.begin(),v.end(),c2[i])-v.begin(); } len=v.size(); return; } int main() { #ifdef debug freopen("E:\\Documents\\code\\input.txt","r",stdin); freopen("E:\\Documents\\code\\output.txt","w",stdout); #endif while(cin>>w>>h&&w+h) { cin>>n; for(int i=0;i<n;++i) { cin>>X1[i]>>Y1[i]>>X2[i]>>Y2[i]; --X2[i];--Y2[i]; } compress(X1,X2,w); compress(Y1,Y2,h); cls(G); for(int i=0;i<n;++i) for(int x=X1[i];x<=X2[i];++x) for(int y=Y1[i];y<=Y2[i];++y) G[y][x]=1; int ans=0; for(int y=0;y<h;++y) { for(int x=0;x<w;++x) { if(G[y][x]) continue; G[y][x]=1; ++ans; int xx,yy,nx,ny; queue<pair<int,int> > BFS; BFS.push(make_pair(x,y)); while(BFS.size()) { int yy=BFS.front().second,xx=BFS.front().first; BFS.pop(); for(int k=0;k<4;++k) { nx=xx+dx[k];ny=yy+dy[k]; if(nx>=0&&nx<w&&ny>=0&&ny<h&&!G[ny][nx]) { BFS.push(make_pair(nx,ny)); G[ny][nx]=1; } } } } } cout<<ans<<endl; } return 0; }
相关文章推荐
- Aizu - 0531 Paint Color (坐标离散化)
- 离散化+BFS HDOJ 4444 Walk
- 【坐标离散化】AOJ0531- Paint Color
- HDU 5925 Coconuts 【离散化+BFS】 (2016CCPC东北地区大学生程序设计竞赛)
- hdu5925 Coconuts 【离散化+bfs】
- HDU 5925 Coconuts 【离散化+BFS】 (2016CCPC东北地区大学生程序设计竞赛)
- HDU 5925 Coconuts(离散化+bfs, 好题)
- FZU 2235 国王的出游【离散化+Bfs】
- PKU3277离散化+线段树
- Sicily 1799 Slides(离散化处理)
- poj 1177 又是一道十分恶心到线段树。 主要是用线段树到区间操作。可以用来节省线性查找的时间。 离散化也十分好的一道题。
- pku2528(线段树加离散化)
- POJ_2528 Mayor's posters(线段树+离散化)
- 数据的离散化
- POJ3666 Making the Grade [DP,离散化]
- poj 2528 Mayor's posters(扫描线+堆维护||离散化+线段树)
- [线段树+离散化]LightOJ 1089 - Points in Segments (II)
- HDU 4325 线段树离散化
- poj 2528 线段树 (先离散化)
- AIZU 1259