读完题,这是一道和bfs联通快有关的搜索题,肯定要搜索一些联通快,而这道题的难点在于如何判断当前的联通快属于山峰还是山谷。
因此,我们设计一个算法,在用bfs求联通快的同时,判断当前联通快是山峰山谷或者啥都不是。
具体地,我们像往常一样搜索联通快,若扩展的节点高度与当前联通快不同,则开始判断:如果大于,表明当前联通快不可能为山峰。反之同理。
因此我们得到了一个完整的算法。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <algorithm> 6 typedef long long ll; 7 inline int read() { 8 int ret=0,f=1; 9 char c=getchar(); 10 while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();} 11 while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar(); 12 return ret*f; 13 } 14 using namespace std; 15 int a[1010][1010],vis[1010][1010],ans1,ans2,n,sum1,sum2; 16 queue<int> qx; 17 queue<int> qy; 18 int fx[8]={-1,-1,-1,0,0,1,1,1,}; 19 int fy[8]={-1,0,1,-1,1,-1,0,1}; 20 void bfs(int sx,int sy) { 21 vis[sx][sy]=1; 22 qx.push(sx); 23 qy.push(sy); 24 while(!qx.empty()) { 25 int nowx=qx.front(); 26 int nowy=qy.front(); 27 qx.pop(); qy.pop(); 28 for(int i=0;i<8;i++) { 29 int xx=nowx+fx[i]; 30 int yy=nowy+fy[i]; 31 if(xx<1||xx>n||yy<1||yy>n) continue ; 32 if(a[xx][yy]==a[nowx][nowy]&&!vis[xx][yy]) { 33 vis[xx][yy]=1; 34 qx.push(xx); 35 qy.push(yy); 36 } 37 else { 38 if(a[xx][yy]>a[nowx][nowy]) sum1=0; 39 if(a[xx][yy]<a[nowx][nowy]) sum2=0; 40 } 41 } 42 } 43 } 44 int main() { 45 n=read(); 46 for(int i=1;i<=n;i++) 47 for(int j=1;j<=n;j++) 48 a[i][j]=read(); 49 bool pd=1; 50 for(int i=1;i<=n;i++) 51 for(int j=1;j<=n;j++) 52 if(a[i][j]!=a[1][1]) pd=0; 53 if(pd) { 54 puts("1 1"); 55 return 0; 56 } 57 for(int i=1;i<=n;i++) 58 for(int j=1;j<=n;j++) 59 if(!vis[i][j]) { 60 sum1=sum2=1; 61 bfs(i,j); 62 ans1+=sum1; 63 ans2+=sum2; 64 } 65 printf("%d %d ",ans1,ans2); 66 return 0; 67 }