I‘m stuck!
问题描述
给定一个R行C列的地图,地图的每一个方格可能是‘#‘, ‘+‘, ‘-‘, ‘|‘, ‘.‘, ‘S‘, ‘T‘七个字符中的一个,分别表示如下意思: ‘#‘: 任何时候玩家都不能移动到此方格; ‘+‘: 当玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非‘#‘方格移动一格; ‘-‘: 当玩家到达这一方格后,下一步可以向左右两个方向相邻的一个非‘#‘方格移动一格; ‘|‘: 当玩家到达这一方格后,下一步可以向上下两个方向相邻的一个非‘#‘方格移动一格; ‘.‘: 当玩家到达这一方格后,下一步只能向下移动一格。如果下面相邻的方格为‘#‘,则玩家不能再移动; ‘S‘: 玩家的初始位置,地图中只会有一个初始位置。玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非‘#‘方格移动一格; ‘T‘: 玩家的目标位置,地图中只会有一个目标位置。玩家到达这一方格后,可以选择完成任务,也可以选择不完成任务继续移动。如果继续移动下一步可以向上下左右四个方向相邻的任意一个非‘#‘方格移动一格。 此外,玩家不能移动出地图。 请找出满足下面两个性质的方格个数: 1. 玩家可以从初始位置移动到此方格; 2. 玩家不可以从此方格移动到目标位置。
输入格式
输入的第一行包括两个整数R 和C,分别表示地图的行和列数。(1 ≤ R, C ≤ 50)。 接下来的R行每行都包含C个字符。它们表示地图的格子。地图上恰好有一个‘S‘和一个‘T‘。
输出格式
如果玩家在初始位置就已经不能到达终点了,就输出“I‘m stuck!”(不含双引号)。否则的话,输出满足性质的方格的个数。
样例输入
5 5
--+-+
..|#.
..|##
S-+-T
####.
样例输出
2
思路:广度优先搜索//从初始位置开始和从终点两个位置位起点,找出从起点可以到达而从终点不能到达的点
代码如下:
#include <iostream> #include <algorithm> #include <string.h> #include <cmath> #include <stdio.h> #include <queue> #define maxn 60 char mmap[maxn][maxn]; int vis[maxn][maxn]; //标记从起点出发 int vis1[maxn][maxn]; //标记从终点出发 int dy[4] = {0, 0, -1, 1}; //转向数组 int dx[4] = {1, -1, 0, 0}; int n, m; int num[maxn][maxn][maxn][maxn];//记录一些路径 using namespace std; struct Node//定义结构体 { int x; int y; Node() {} Node(int _x, int _y) { x = _x; y = _y; } } node[maxn]; Node st, ed; int check(Node a)//节点是否合法 { if(a.x >= 0 && a.x < n && a.y >= 0 && a.y < m && mmap[a.x][a.y] !=‘#‘) { return 1; } return 0; } int get(char c, int& u, int& v)//判断当前可以走的方向 { if(c == ‘-‘) { u = 2; v = 4; } else if(c == ‘|‘) { u = 0; v = 2; } else if(c == ‘.‘) { u = 0; v = 1; } else { u = 0; v = 4; } } queue<Node>que; int bfs() { while(!que.empty()) { que.pop(); } que.push(st); //从起点走 vis[st.x][st.y] = 1; Node tmp, now; while(!que.empty()) { tmp = que.front(); que.pop(); int u, v; get(mmap[tmp.x][tmp.y], u, v); for(int i = u; i < v; i++) { now.x = tmp.x + dx[i]; now.y = tmp.y + dy[i]; if(check(now)) { num[tmp.x][tmp.y][now.x][now.y] = 1; if(!vis[now.x][now.y]) { vis[now.x][now.y] = 1; que.push(now); } } } } if(vis[ed.x][ed.y] == 0) { puts("I‘m stuck!");// 若未到达 return 0; } que.push(ed); //从终点走 while(!que.empty()) { tmp = que.front(); que.pop(); for(int i = 0; i < 4; i++) { now.x = tmp.x + dx[i]; now.y = tmp.y + dy[i]; if(check(now) && vis1[now.x][now.y] == 0 && num[now.x][now.y][tmp.x][tmp.y]) { vis1[now.x][now.y] = 1; que.push(now); } } } int ans = 0; for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { if(vis[i][j] == 1 && vis1[i][j] == 0) { ans++; } } } printf("%d\n", ans); return 0; } int main() { scanf("%d %d", &n, &m); memset(vis, 0, sizeof(vis)); memset(vis1, 0, sizeof(vis1)); memset(num, 0, sizeof(num)); for(int i = 0; i < n; i++) { scanf("%s", mmap[i]); for(int j = 0; j < m; j++) { if(mmap[i][j] == ‘S‘) { st.x = i; st.y = j; } if(mmap[i][j] == ‘T‘) { ed.x = i; ed.y = j; } } } bfs(); return 0; }
CCF-I'm stuck!(BFS)