2020ICPC·小米 网络选拔赛第一场 I.Walking Machine
题目:
Given a maze of size n×m, where upper left corner is (1,1)
and lower right corner is (n, m). For each cell (x, y) , there is exactly one character c (c∈{W,A,S,D}) on it, denoting the moving restriction:
- If c=W , you can only go up from this cell, specifically go from (x, y)to (x-1, y)
- If c=A , you can only go left from this cell, specifically go from(x,y) to (x,y−1)
- If c=S, you can only go down from this cell, specifically go from(x,y) to (x+1,y)
- If c=D , you can only go right from this cell, specifically go from (x,y) to (x,y+1)
We say one is out if x < 1 or x > n or y < 1 or y > m holds, now you should determine the number of cells that one can be out if start walking on it.
输入描述:
The first line contains two integers n,m (1≤n,m≤1000), denoting the size of the maze.
Following n lines each contains a string of length m , where the j-th character in i-th line s(i, j) ( s (i,j)∈{W,A,S,D}) denotes the character on cell (i, j).
输出描述:
Only one line containing one integer, denoting the number of cells that can make one out.
输入
3 4
DDSD
AWAA
WASD
输出
6
说明
The 6 cells are (1, 4),(2, 1),(3, 1),(3, 2),(3, 3),(3, 4) respectively.
题意:判断一个迷宫中有几个点可以走出去,每个点会有一个方向,也就是我们键盘上的WASD(向上、向左、向下、向右)
题解:我首先是把最外围那圈能直接走出去的做一个标记(其实不用也行,可以直接搜),然后其他的点依次判断是否能走出去,重点就是几个剪枝,假如之前遍历过的点并且不能走出,那么这些所有的点下一次走到的时候肯定走不出去,如果之前遍历的点可以走出去,那么所有的点下次被走到时肯定肯定可以走出去。(bfs也可做)
代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
const int N = 1005;
char map[1005][1005];
int can[N][N], vis[N][N]; //vis:标记之前是否走过, can:是否一定可以走出去或者走不出去
int cnt = 0;
int flag = 0;
int n, m;
void dfs(int x, int y)
{
if(can[x][y] == 1) //如果之前已经遍历过, 该点可以到达
{
cnt++;
flag = 1; //标记一下可以走出迷宫
return;
}
if(can[x][y] == -1) return; //该点不能走出去
if(vis[x][y])
{
can[x][y] = -1; //重复遍历, 一定无法走出去
return;
}
if(map[x][y] == 'W' )
{
vis[x][y] = 1;
dfs(x - 1,y);
vis[x][y] = 0;
if(flag == 0) can[x][y] = -1; //如果最后无法到达, 将此次遍历过的所有点标为不可行
else can[x][y] = 1; //否则一定可以走出去(比赛的时候忘写了,直接T)
}
else if(map[x][y] == 'S')
{
vis[x][y] = 1;
dfs(x + 1,y);
vis[x][y] = 0;
if(flag == 0) can[x][y] = -1;
else can[x][y] = 1;
}
else if(map[x][y] == 'A' )
{
vis[x][y] = 1;
dfs(x,y - 1);
vis[x][y] = 0;
if(flag == 0) can[x][y] = -1;
else can[x][y] = 1;
}
else if(map[x][y] == 'D')
{
vis[x][y] = 1;
dfs(x,y + 1);
vis[x][y] = 0;
if(flag == 0) can[x][y] = -1;
else can[x][y] = 1;
}
}
int main()
{
freopen("cin.in", "r", stdin);
freopen("cout.out", "w", stdout);
memset(can, 0, sizeof(can));
memset(vis, 0, sizeof(vis));
scanf("%d%d", &n, &m);
getchar();
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
scanf("%c", &map[i][j]);
if(i == 1 || j == 1 || i == n || j == m)
{
if(j == 1 && map[i][j] == 'A') can[i][j] = 1;
if(i == 1 && map[i][j] == 'W') can[i][j] = 1;
if(j == m && map[i][j] == 'D') can[i][j] = 1;
if(i == n && map[i][j] == 'S') can[i][j] = 1;
}
}
getchar();
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
flag = 0;
if(can[i][j] == 1) cnt++;
else dfs(i, j);
}
}
cout << cnt << endl;
return 0;
}

浙公网安备 33010602011771号