CCF 201312-5 I’m stuck!

Posted shenben

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CCF 201312-5 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
样例说明
  如果把满足性质的方格在地图上用‘X‘标记出来的话,地图如下所示:
  --+-+
  ..|#X
  ..|##
  S-+-T
  ####X

 

#include<stdio.h>
#include<iostream>
#include<vector>
#include<queue>
#define mp make_pair
#define pb emplace_back
#define fi first
#define se second
using namespace std;
typedef pair<int,int> pir;
const int N=55;
char da[N][N];vector<pir>dir[6];
int ans,n,m;;bool tim,v1[N][N],v2[N][N];
inline bool border(const int x,const int y){
    return x<1||y<1||x>n||y>m||da[x][y]==#;
}
inline int value(const int x,const int y){
    const char &c=da[x][y];int v=0;
    switch(c){
        case +:v=1;break;
        case S:v=1;break;
        case T:v=1;break;
        case -:v=2;break;
        case |:v=3;break;
        case .:v=4;break;
    }
    return v;
}
void bfs(pir S){//(Sx,Sy)->(i,j) available
    queue<pir>q;q.push(S);
    for(int cx,cy,nx,ny;!q.empty();){
        pir t=q.front();q.pop();
        cx=t.fi;cy=t.se;
        if(border(cx,cy)) continue;
        if(v1[cx][cy]) continue;v1[cx][cy]=1;
        int whe=value(t.fi,t.se);
        if(whe) for(auto &i:dir[whe]){
            nx=cx+i.fi;
            ny=cy+i.se;
            if(v1[nx][ny]) continue;
            q.push(mp(nx,ny));
        }
    } 
}
void BFS(pir S){//(i,j)->(Tx,Ty) available
    queue<pir>q;q.push(S);
    for(int cx,cy,nx,ny;!q.empty();){
        pir t=q.front();q.pop();
        cx=t.fi;cy=t.se;
        if(border(cx,cy)) continue;
        if(v2[cx][cy]) continue;v2[cx][cy]=1;
        for(int i=0;i<4;i++){
            nx=cx+dir[1][i].fi;
            ny=cy+dir[1][i].se;
            if(da[nx][ny]==S||da[nx][ny]==T||da[nx][ny]==+||
                i==0&&da[nx][ny]==.||i<2&&da[nx][ny]==|||i>1&&da[nx][ny]==-){
                q.push(mp(nx,ny));     
            }
        }
    } 
}
void work1(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(da[i][j]==S){
                bfs(mp(i,j));
                return ;
            }
        }
    }
}
void work2(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(da[i][j]==T){
                if(!v1[i][j]){puts("I‘m stuck!");exit(0);}
                BFS(mp(i,j));
                return ;
            }
        }
    }
}
int main(){
    dir[1].pb(mp(-1,0));dir[1].pb(mp(1,0));dir[1].pb(mp(0,-1)); dir[1].pb(mp(0,1));
    dir[2].pb(mp(0,1)); dir[2].pb(mp(0,-1));
    dir[3].pb(mp(1,0)); dir[3].pb(mp(-1,0));
    dir[4].pb(mp(1,0));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%s",da[i]+1);
    work1();
    work2();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(v1[i][j]&&!v2[i][j]) ans++;
        }
    }
    printf("%d
",ans);
    return 0;
}

 

以上是关于CCF 201312-5 I’m stuck!的主要内容,如果未能解决你的问题,请参考以下文章

CCF-I'm stuck!(BFS)

CCF 201312-5I’m stuck! (暴力,BFS)

CCF_I’m stuck!_bfs

I’m stuck!题解

I’m stuck!(BFS)

I’m stuck!