I'm stuck! ccf 2013年12月第5題

問題描述
  給定一個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

總結一句話:想着省runtime真的是作死,對於ccf這種考試來說,除非實在不能暴力,那麼就一定要暴力,不說了都是淚,貢獻了一次ERROR,思路就是先對起點進行BFS,標記出到達的點,在從達到的點中進行bfs,看是否能到達終點,一句話,能暴力一定要暴力,不要聖母!

#include <iostream>
#include <map>
#include <queue>
#include <cstring>

using namespace std;

const int maxn = 55;
char G[maxn][maxn];
int vis[2][maxn][maxn];
int r,c;
int sx,sy,ex,ey;
map<char,int> m,m1;

void initmap () {
    m.insert(make_pair('+',4));m1.insert(make_pair('+',0));
    m.insert(make_pair('-',2));m1.insert(make_pair('-',1));
    m.insert(make_pair('|',2));m1.insert(make_pair('|',2));
    m.insert(make_pair('.',1));m1.insert(make_pair('.',3));
}
int f[4][4][2] = {
    0,1,0,-1,-1,0,1,0,
    0,1,0,-1,0,0,0,0,
    -1,0,1,0,0,0,0,0,
    1,0,0,0,0,0,0,0
};

struct Node {
    int x,y;
    Node(int a,int b):x(a),y(b) {}
};

bool check1 (int x,int y,int type) {
    if (x>=1 && x<=r && y>=1 && y<=c && G[x][y]!='#' && !vis[type][x][y])
        return true;
    else
        return false;
}

void bfs1 (int type , int x , int y) {
    if (type)
        memset(vis[type],0,sizeof(vis[type]));
    queue<Node> q;
    q.push(Node(x,y));
    vis[type][x][y] = 1;

    while (!q.empty()) {
        Node t = q.front() ; q.pop();
        int x = t.x , y = t.y;
        for (int i = 0 ; i < m[G[x][y]] ; i++) {
            int tx = x+f[m1[G[x][y]]][i][0];              
            int ty = y+f[m1[G[x][y]]][i][1];       
            if (check1(tx,ty,type)) {
                vis[type][tx][ty] = 1;
                q.push(Node(tx,ty));
            }
        }
        if (type && vis[type][ex][ey])
            break;
    }
}

int main () {
    int ans = 0;
    cin >> r >> c;
    for (int i = 1 ; i <= r ; i++) 
        for (int j = 1 ; j <= c ; j++) {
            char tmp;
            cin >> tmp;
            if (tmp == 'S') {sx=i;sy=j;tmp='+';}
            else if (tmp == 'T') {ex=i;ey=j;tmp='+';}
            G[i][j] = tmp;
        }
    initmap();
    bfs1(0,sx,sy);

    if (!vis[0][ex][ey]) {
        cout << "I'm stuck!" << endl;
        return 0;
    }

    vis[0][sx][sy] = vis[0][ex][ey] = 0;
    for (int i = 1 ; i <= r ; i++) 
        for (int j = 1 ; j <= c ; j++) {
            if (vis[0][i][j]) {
                bfs1(1,i,j);
                if (!vis[1][ex][ey]) 
                    ans++;
            }
        }
    cout << ans << endl;
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章