I’m stuck!
问题描述
试题编号: | 201312-5 |
试题名称: | I’m stuck! |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 给定一个R行C列的地图,地图的每一个方格可能是'#', '+', '-', '|', '.', 'S', 'T'七个字符中的一个,分别表示如下意思: 输入格式 输入的第一行包括两个整数R 和C,分别表示地图的行和列数。(1 ≤ R, C ≤ 50)。 输出格式 如果玩家在初始位置就已经不能到达终点了,就输出“I'm stuck!”(不含双引号)。否则的话,输出满足性质的方格的个数。 样例输入 5 5 样例输出 2 样例说明 如果把满足性质的方格在地图上用'X'标记出来的话,地图如下所示: |
解题思路:
分析题意以后,此题是求解是死路的点的个数,是典型的bfs问题,与普通的迷宫问题不同,在每个格子所走的方向与该格子的符号有关。
不难想到解题采用两次遍历即可,第一次我们逆向遍历得出所有能够到达点T的点,第二次遍历我们获得从S出发能够到达的所有点,接着我们判断如果第一次遍历没有到达S点,那么我们直接输出“I’m stuck!”,否则我们遍历vis2,如果vis2[i][j]==1&&vis[i][j]!=1即能够从s出发到达该点,但是该点不能到达T点,那么我们sum++,最好输出sun即可。
算法流程:
一、首先我们从目标点T逆向遍历,假设x点能够到达点T,那么能够到达x点的点一定能够到达点T。因此我们逆向遍历T点,将能够到达T点的点标注为1。vis[i][j]=1;
以某点t1为例,分为上下左右走的四种情况(在判断点前需要判断是否走出了迷宫):
1、目标点的右侧点rp,如果是'S'或者'+'或者'-'那么到达lp点以后一定能够到达目标点t1。
2、目标点的右侧点lp,如果是'S'或者'+'或者'-'那么到达lp点以后一定能够到达目标点t1。
3、目标点的下侧点dp,如果是'S'或者'+'或者'|'那么到达dp点以后一定能够到达目标点t1。
4、目标点的上侧点dp,如果是'S'或者'+'或者'|'或者'.'那么到达dp点以后一定能够到达目标点t1。
每次走过一个点我们都要使得vis[xi][yi]=1,标识
二、然后我们从S点出发,依次遍历所有的图,能够到达的位置标注vis2[i][j]标注为1。
我们的上下左右的遍历与该点的符号相关。
三、最后我们进行处理,如果点S vis[xs][ys]在逆向遍历时没有赋值为1,那么我们就直接输出否则到四。
四、我们遍历所有的vis2,即找出从S出发能够到达的点,接着输出vis2[i][j]==1&&vis[i][j]!=1的点的数量即可。
程序代码:
#include <iostream>
#include<cstring>
#define rep(i,n) for(int i = 0 ;i<n;i++)
using namespace std;
char *mp= "#+-|.ST\0";
char Map[60][60];
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
int vis[60][60];
int vis2[60][60];
int xs,ys,xt,yt;
int r,c;
void bfs(int x,int y){
rep(i , 4){
int x1 = x+dx[i];
int y1 = y+dy[i];
if(x1>=0&&x1<r&&y1>=0&&y1<c&&vis[x1][y1]!=1){
switch(i){
case 0:
if(Map[x1][y1]=='S'||Map[x1][y1]=='+'||Map[x1][y1]=='-'){
vis[x1][y1] = 1;
bfs(x1,y1);
}
break;
case 1:
if(Map[x1][y1]=='S'||Map[x1][y1]=='+'||Map[x1][y1]=='-'){
vis[x1][y1] = 1;
bfs(x1,y1);
}
break;
case 2:
if(Map[x1][y1]=='S'||Map[x1][y1]=='+'||Map[x1][y1]=='|'){
vis[x1][y1] = 1;
bfs(x1,y1);
}
break;
case 3:
if(Map[x1][y1]=='.'||Map[x1][y1]=='S'||Map[x1][y1]=='+'||Map[x1][y1]=='|'){
vis[x1][y1] = 1;
bfs(x1,y1);
}
break;
}
}
}
}
void bfs2(int x,int y){
if(Map[x][y]=='S'||Map[x][y]=='+'||Map[x][y]=='T'){
rep(i,4){
int x1 = x+dx[i];
int y1 = y+dy[i];
if(x1>=0&&x1<r&&y1>=0&&y1<c&&vis2[x1][y1]!=1){
if(Map[x1][y1]!='#'){
vis2[x1][y1]=1;
bfs2(x1,y1);
}
}
}
}else if(Map[x][y]=='-'){
rep(i,4){
if(i<2){
int x1 = x+dx[i];
int y1 = y+dy[i];
if(x1>=0&&x1<r&&y1>=0&&y1<c&&vis2[x1][y1]!=1){
if(Map[x1][y1]!='#'){
vis2[x1][y1]=1;
bfs2(x1,y1);
}
}
}
}
}else if(Map[x][y]=='|'){
rep(i,4){
if(i>=2){
int x1 = x+dx[i];
int y1 = y+dy[i];
if(x1>=0&&x1<r&&y1>=0&&y1<c&&vis2[x1][y1]!=1){
if(Map[x1][y1]!='#'){
vis2[x1][y1]=1;
bfs2(x1,y1);
}
}
}
}
}else if(Map[x][y]=='.'){
rep(i,4){
if(i==2){
int x1 = x+dx[i];
int y1 = y+dy[i];
if(x1>=0&&x1<r&&y1>=0&&y1<c&&vis2[x1][y1]!=1){
if(Map[x1][y1]!='#'){
vis2[x1][y1]=1;
bfs2(x1,y1);
}
}
}
}
}
}
int main(){
cin>>r>>c;
for(int i =0;i<r;i++) cin>>Map[i];
rep(i,r){
for(int j = 0 ; Map[i][j]!='\0';j++){
vis[i][j] = 0;
vis2[i][j] = 0;
if(Map[i][j] == 'S'){
xs = i;
ys = j;
vis2[xs][ys] = 1;
}else if (Map[i][j]=='T'){
xt = i;
yt = j;
vis[xt][yt] = 1;
}
}
}
bfs(xt,yt);
bfs2(xs,ys);
int sum = 0;
if(vis[xs][ys]!=1){
cout<<"I'm stuck!"<<endl;
}else {
rep(i,r){
rep(j,c){
if(vis2[i][j]==1&&vis[i][j]!=1){
sum ++;
//cout<<i<<" "<<j<<endl;
}
}
}
cout<<sum<<endl;
}
}