(maze.cpp/c/pas)
Description
Karles 和朋友到迷宫玩耍,没想到遇上了 10000000 年一次的大洪水,好在 Karles 是一个喜欢思考的人,他发现迷宫的地形和洪水有如下性质:
①迷宫可以被看做是一个 N*M 的矩形方阵,其中左上角坐标为(1,1),右下角坐标为(n,m),每个格子(i,j)都有一个高度 h(i,j)。
②洪水从(sx,sy)开始,如果一个格子被洪水淹没,那这个格子四周比它低(或相同)的格子也会被淹没。
现在 Karles 想请你帮忙算算,有多少个格子不会被淹没,以及 Karles 想问一下格子(x,y)是否被淹没,如果被淹没的话就输出”Yes”,否则输出”No”。
Input
第一行包含两个整数 n,m。
以下 n 行,每行 m 个数,第 i 行第 j 个数表示格子高度 h(i,j)。
下面一行包含两个整数 sx,sy,表示最初被洪水淹没的格子。
下面一行包含一个整数 q,表示询问的数量。
最后 q 行每行包含两个整数 x,y,表示询问的格子。
Output
输出的第一行,为永远不会被淹没的格子的数量。
以下 q 行,为格子被淹没的情况,输出”Yes”或者”No”(不包含引号)
Example
maze.in
3 3
1 2 3
2 3 4
3 4 5
2 2
2
1 2
2 3
maze.out
5
Yes
No
Hint
对于 10%的数据,(sx,sy)为迷宫内的最高点。
对于 30%的数据,1<=N,M<=5,q=1。
对于 60%的数据,1<=N,M<=100,q<=100。
对于 100%的数据,1<=N,M<=2000,q<=1000。
解题思路:
因为题目的意思为从一个起点开始,
向它的四周扩展,所以开2个数组,
为移动方向,如果找到比它低的,计数器就++;
最终输出总的m*n-计数器的数;
上代码:
#include<cstdio> #include<queue> using namespace std; const int M = 2001; int n,m,tot=1,T,x,y; int dx[5] = {0,1,-1,0,0}; //搜索的方向 int dy[5] = {0,0,0,1,-1}; bool vis[M][M];//记录是否能够被淹没,初始化均为0 int g[M][M],x1,y1; struct data { int x,y; }; queue<data>q; void bfs() { data u,v; vis[x1][y1]=true; u.x=x1,u.y=y1; q.push(u); while(!q.empty()) { u=q.front(); q.pop(); x=u.x,y=u.y; for(int i=1; i<=4; i++) { //扩展的四个方向 int xx=x+dx[i],yy=y+dy[i]; if(yy>=1&&xx>=1&&yy<=m&&xx<=n&&g[xx][yy]<=g[x][y]&&!vis[xx][yy]) { vis[xx][yy]=true;//进行标记 tot++; v.x=xx,v.y=yy; q.push(v); } } } } int main() { freopen("maze.in","r",stdin); freopen("maze.out","w",stdout); scanf("%d %d",&n,&m); for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) scanf("%d",&g[i][j]); scanf("%d %d",&x1,&y1); bfs(); printf("%d ",n*m-tot);//总共的减去被淹没的 scanf("%d",&T); while(T--) { scanf("%d %d",&x,&y); if(vis[x][y]) printf("Yes "); else printf("No "); } fclose(stdin);fclose(stdout); return 0; }