BZOJ1102: [POI2007]山峰和山谷Grz
联通:八联通;山峰:一相同数字联通块周围数字都比他们小;山谷:一相同数字联通块周围数字都比他们大。问山峰山谷数。
搜。
1 #include<stdio.h> 2 #include<string.h> 3 //#include<queue> 4 #include<stdlib.h> 5 #include<algorithm> 6 #include<iostream> 7 using namespace std; 8 9 #define LL long long 10 int qread() 11 { 12 char c; int s=0,t=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (t=-1); 13 do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*t; 14 } 15 16 //Pay attention to LL and double of qread!!!! 17 18 int n; 19 #define maxn 1011 20 int mp[maxn][maxn]; 21 22 int qx[maxn*maxn],qy[maxn*maxn],head,tail; 23 bool vis[maxn][maxn]; 24 int A=0,B=0; 25 const int dx[]={0,0,1,1,1,-1,-1,-1},dy[]={1,-1,1,0,-1,1,0,-1}; 26 bool cf(int x,int y) 27 { 28 for (int i=0;i<8;i++) 29 { 30 int nx=x+dx[i],ny=y+dy[i]; 31 if (nx<1 || nx>n || ny<1 || ny>n || mp[nx][ny]==mp[x][y]) continue; 32 if (mp[nx][ny]>mp[x][y]) return 0; 33 } 34 return 1; 35 } 36 bool cg(int x,int y) 37 { 38 for (int i=0;i<8;i++) 39 { 40 int nx=x+dx[i],ny=y+dy[i]; 41 if (nx<1 || nx>n || ny<1 || ny>n || mp[nx][ny]==mp[x][y]) continue; 42 if (mp[nx][ny]<mp[x][y]) return 0; 43 } 44 return 1; 45 } 46 void bfs(int sx,int sy) 47 { 48 bool f=1,g=1; 49 head=0; tail=1; qx[0]=sx; qy[0]=sy; vis[sx][sy]=1; 50 while (head!=tail) 51 { 52 int xx=qx[head],yy=qy[head]; head++; 53 if (f) f=cf(xx,yy); if (g) g=cg(xx,yy); 54 for (int i=0;i<8;i++) 55 { 56 int nx=xx+dx[i],ny=yy+dy[i]; 57 if (nx<1 || nx>n || ny<1 || ny>n || vis[nx][ny] || mp[nx][ny]!=mp[xx][yy]) continue; 58 vis[nx][ny]=1; qx[tail]=nx; qy[tail]=ny; tail++; 59 } 60 } 61 if (f) A++; if (g) B++; 62 } 63 64 int main() 65 { 66 n=qread(); 67 for (int i=1;i<=n;i++) 68 for (int j=1;j<=n;j++) 69 mp[i][j]=qread(); 70 for (int i=1;i<=n;i++) 71 for (int j=1;j<=n;j++) 72 if (!vis[i][j]) bfs(i,j); 73 printf("%d %d\n",A,B); 74 return 0; 75 }