BZOJ1102: [POI2007]山峰和山谷Grz
【传送门:BZOJ1102】
简要题意:
给出一张n*n的图,每个格子有一个高度,一个格子的八个方向为它的相邻格子,高度相同的相邻的格子形成连通块,一个连通块的相邻格子的高度如果都比连通块的高度大,则这个连通块称为山谷,如果都比连通块高度小,则称为山峰
特殊的,如果整张图的高度都相同,则整张图既为山峰又为山谷
求整张图的山峰和山谷数量
题解:
直接dfs找连通块,顺便判断一个连通块四周的高度情况
结果爆栈了,RoseD飞我说会递归1000000层,所以爆栈
懒得改,直接写了个手工栈过了
参考代码:
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<queue> using namespace std; int dx[9]={0,1,-1,0,0,-1,-1,1,1}; int dy[9]={0,0,0,1,-1,-1,1,-1,1}; int a[1100][1100],n; bool v[1100][1100]; bool b1,b2;int tx,ty; struct node { int x,y; }; queue<node> q; int cur[1100][1100]; bool check(int tx,int ty,int x,int y) { if(tx<1||ty<1||tx>n||ty>n||(a[x][y]==a[tx][ty]&&v[tx][ty]==true)) return false; return true; } void dfs(int x,int y) { q.push((node){x,y}); cur[x][y]=1; while(q.empty()==0) { node tno=q.front(); int x=tno.x,y=tno.y; v[x][y]=true; while(cur[x][y]<=8&&(check(x+dx[cur[x][y]],y+dy[cur[x][y]],x,y)==false)) cur[x][y]++; if(cur[x][y]==9) { q.pop(); continue; } int tx=x+dx[cur[x][y]],ty=y+dy[cur[x][y]]; if(a[tx][ty]>a[x][y]) b1=true; else if(a[tx][ty]<a[x][y]) b2=true; else { if(v[tx][ty]==false) { q.push((node){tx,ty}); cur[tx][ty]=1; } } cur[x][y]++; } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&a[i][j]); memset(v,false,sizeof(v)); int d1=0,d2=0; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(v[i][j]==false) { b1=b2=false; dfs(i,j); if(b1==false&&b2==true) d1++; else if(b1==true&&b2==false) d2++; } } } if(d1==0&&d2==0){printf("1 1\n");return 0;} else printf("%d %d\n",d1,d2); return 0; }
渺渺时空,茫茫人海,与君相遇,幸甚幸甚