BFS2

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<queue>
#include<algorithm>
#include<vector>
#include<cString>
#define aMax 60
using namespace std;
struct node{
    int x;
    int y;
    char c;
    node(){}
    node(int xx,int yy,int cc){
        x = xx;y = yy;c = cc;
    }
};
char record[aMax][aMax];//记录输入的内容
int visited[aMax][aMax];//标志是否被访问,如果被访问,说明起点可以到达
int change[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};//注意此处的上下左右
int R,C,staX,staY;
queue<node>q;
int judge(int a,int xi,int yi){
    while(!q.empty()){q.pop();}
    int visit[aMax][aMax];
    memset(visit,0,sizeof(visit)); //此处为何第二次调用此函数的时候,visit的值来保留着,这个不是局部变量吗???
    char s = record[xi][yi];
    q.push(node(xi,yi,s));
    node tmp;
    int flag = 0;//标志是否可以到达终点;
    while(!q.empty()){
        tmp = q.front();

        //cout<<tmp.c<<endl;
        q.pop();
        int x = tmp.x;int y = tmp.y;char c = tmp.c;
        visit[x][y] = 1;
        int min1 = 0,max1 = 0;
        if(c=='S'){min1 = 0;max1 = 4;}
        if(c=='T'){min1 = 0;max1 = 4;}
        if(c=='+'){min1 = 0;max1 = 4;}
        if(c=='-'){min1 = 2;max1 = 4;}
        if(c=='|'){min1 = 0;max1 = 2;}
        if(c=='.'){min1 = 1;max1 = 2;}
        for(int i=min1;i<max1;i++){
            int xx = x+change[i][0];int yy = y+change[i][1];
            if(visit[xx][yy]!=1&&record[xx][yy]!='#'&&xx>=1&&x<=R&&yy>=1&&yy<=C){
                //cout<<a<<endl;
                //if(a==0){cout<<record[x][y]<<endl;}
                visit[xx][yy] = 1;
                if(record[xx][yy] == 'T')
                    flag = 1;
                q.push(node(xx,yy,record[xx][yy]));

            }

        }
    }
    if(a==1){
         for(int i=1;i<=R;i++){
            for(int j=1;j<=C;j++){
                visited[i][j] = visit[i][j];
                //cout<<visit[i][j];
            }
        }
        //cout<<endl;
    }
    return flag;
}
int main()
{

    cin>>R>>C;
    for(int i=1;i<=R;i++){
        for(int j=1;j<=C;j++){
            char s;
            cin>>s;
            if(s=='S'){
                staX = i;staY = j;
            }
            record[i][j] = s;
        }
    }

    int flag0 = judge(1,staX,staY);
    if(flag0 == 0){
        cout<<"I'm stuck!"<<endl;
    }else{
        int sum = 0;
        for(int i=1;i<=R;i++){
            for(int j=1;j<=C;j++){
                if(visited[i][j]==1&&record[i][j]!='S'&&record[i][j]!='T'){
                    int flag = judge(0,i,j);
                    if(flag==0){
                        sum++;
                    }
                }
            }
        }
        cout<<sum<<endl;
    }


    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值