迷 宫
(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 maze.out
3 3 5、
1 2 3 Yes
2 3 4 No
3 4 5
2 2
2
1 2
2 3
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。
解题思路:
从最初被淹没的地区开始搜索;搜索向上,右,下,左四个方向搜索,每次前进一;
前进时,下一个搜索的地区满足1.高度比当前低或相等 2.没有出界 3.没被淹没;
全部满足时搜索下一个地区,并标记,这块地已被淹没;
代码实现:
1 #include<iostream> 2 using namespace std; 3 #include<cstdio> 4 int a,b,n,m,t[2010][2010];long long s[2010][2010]; //n,m是行和列;a,b是最先被淹没的;t判断是否已经淹没;s海拔 5 int sum,h,x,y,nexthe,nextzo; 6 int d[5]={-1,0,1,0,-1}; //分别是上,左,下,右四个方向; 7 void so(int he,int zo) 8 { 9 t[he][zo]=1; //表示被淹没; 10 --sum; //剩余的没淹没的地 11 for(int i=0;i<=3;++i) 12 { 13 nexthe=he+d[i]; 14 nextzo=zo+d[i+1]; 15 if((s[he][zo]>=s[nexthe][nextzo])&&(nexthe>0)&&(nexthe<=n)&&(nextzo<=m)&&(nextzo>0)&&!(t[nexthe][nextzo])) //判断是否越界及当前是否比下一个大或等于; 16 { 17 so(he+d[i],zo+d[i+1]); 18 } 19 } 20 } 21 int main() 22 { 23 freopen("maze.in","r",stdin); 24 freopen("maze.out","w",stdout); 25 cin>>n>>m; 26 sum=n*m; 27 for(int i=1;i<=n;++i) 28 { 29 for(int k=1;k<=m;++k) 30 scanf("%ld",&s[i][k]); //输入海拔高度 31 } 32 scanf("%d%d",&a,&b); 33 so(a,b); //从a,b,开始 34 printf("%d ",sum); //没淹没的土地 35 scanf("%d",&h); 36 for(int i=1;i<=h;++i) 37 { 38 scanf("%d%d",&x,&y); 39 if(t[x][y])printf("Yes "); 40 else if(!t[x][y])printf("No "); 41 } 42 fclose(stdin);fclose(stdout); 43 return 0; 44 }