FJNU2019第二次友谊赛-红烧非鸽肉[bfs]

题目链接

FJNU2019第二次友谊赛-红烧非鸽肉

竟然有自己的oj了

题目描述

总所周知,非鸽是一只很欠打的鸽子,于是小胖把非鸽关进一个 \(n \times m\) 的笼子里准备红烧。
机智的小胖是不会把非鸽关在简单的笼子里的,这是个自带迷宫的笼子, 并且这不是一个简单的迷宫
在迷宫中,一些位置是坑地,只有非鸽处于飞行模式才能通过,一些位置是地道,只有非鸽处于挖掘机模式才可以通过,还有一些是墙,非鸽怎么都无法通过,另外还有一些是空地(包括非鸽一开始的位置和出口),非鸽可以自由通过
在其中一些空地上非鸽可以使用技能转换自己的模式(飞行模式->挖掘机模式 \(or\) 挖掘机模式->飞行模式)
但是这需要花费非鸽一个单位的时间
现在知道非鸽在一个单位的时间内可以朝四个方向行走一格,并且一开始非鸽处于飞行模式
当空地可以使用技能使非鸽可以选择就在此空地上使用技能(可以多次使用)或者不使用技能
非鸽太害怕小胖把他红烧了,想让广大网友帮他计算一下最快需要多久才能逃出魔掌

Input

第一行 \(n, m(0 < n, m <= 100)\) 表示图的宽度和长度
接下来输入\(n\)行,描述图
每行有一个长度为\(m\)的字符串。
其中 '@' 代表非鸽一开始在的地方,'$' 代表非鸽要走到的地方,'.' 代表空地,'d'代表地道,'f'代表坑地,'*' 代表非鸽可以使用技能,'#'代表墙。
保证起点和终点只有一个,非鸽可以使用技能的地方都是位于空地上。

Output

输出仅有一行
如果非鸽可以成功逃出,输出"fei pigeon fled in x", \(x\)表示最少需要的时间
如果不可以则输出"fei pigeon is ripe!"

Sample

Input Output
5 5
.d..
.@#..
fd#..
.d..f
d.f$
fei pigeon fled in 18
-- --

分析

由题可知,非鸽确实很欠打, 明显是一道迷宫题,\(n,m\)的范围也较小
求最短需要的时间选用\(bfs\)处理更优
与普通模板题较为不同的是多了一个状态的改变
每个格子选择的状态不同会影响之后是否可以继续走下去,并且状态只有两种
因此可以同时标记每个位置的状态是否走过
即需要一个三维标记数组\(vis[x][y][status]\),表示\((x,y)\)位置的状态\(status\)是否走过
若还没走过则可以遍历他上下左右四个方向
如果当前位置为'*'表示可以转移状态,将一个转移状态后的也压入队列中
状态可以用\(0\)\(1\)分别表示飞行模式和挖掘机模式
然后就是\(bfs\)的模板部分

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <bitset>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <set>
#include <map>

#define  endc       std::ios::sync_with_stdio(false); // 关掉c++流
#define  INOPEN     freopen("in.txt", "r", stdin)
#define  OUTOPEN    freopen("out.txt", "w", stdout)
#define  mes(a, b)  memset(a, b, sizeof a)
#define  qwq(i, j)  for(int i = 0; i < j; ++i)
#define  qeq(i, j)  for(int i = 1; i <= j; ++i)
#define  isdigit(a) ((a)>='0'&&(a)<='9')
#define  xiao(a)    ((a)>='a'&&(a)<='z')
#define  da(a)      ((a)>='A'&&(a)<='Z')
#define  pii        pair<int, int>
#define  lowbit(x)  x & (-x)
#define  fi         first
#define  se         second
#define  lson       id<<1
#define  rson       id<<1|1

typedef unsigned long long int ull;
typedef long long int ll;
const double eps  = 1e-8;
const double pi   = acos(-1.0);
const int    inf  = 0x3f3f3f3f;
const ll     INF  = 1e18;
const int    maxm = 1e6 + 6;
const int    maxn = 100 + 10;
const ll    mod  = 1e9+7;
using namespace std;

template<typename T>void re(T &x){x = 0; int f = 0; char ch = getchar();while(!isdigit(ch)){if(ch == '-') f=1; ch=getchar();}while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0'; ch=getchar();}x = f?-x:x;}
template<typename T>T fpow(T a, ll b) {T ans = 1; while(b) {if(b & 1) ans = a * ans % mod; a = a * a % mod; b >>= 1;}return ans;}

// int n, m, cas, tol = 0;
// int head[maxn];
// struct Edge {int v, next, w;}edge[maxm];
// inline void adde(int u, int v, int w) {edge[tol] = Edge{v, head[u], w}; head[u] = tol++;}


int to[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
int vis[maxn][maxn][2];
char mp[maxn][maxn];
int ans, n, m;
struct node{
    int x, y, statu, step;
    node() : x(0), y(0), statu(0), step(0) {}
    node(int x, int y, int statu, int step) : x(x), y(y), statu(statu), step(step) {}
};
queue<node> q;

void bfs(node s, node t) {
    while(!q.empty())   q.pop();
    memset(vis, 0, sizeof(vis));
    q.push(s);
    while(!q.empty()) {
        node cur = q.front();   q.pop();
        //printf("%d %d %d %d\n", cur.x, cur.y, cur.statu, cur.step);
        if(cur.x == t.x && cur.y == t.y) {
            printf("fei pigeon fled in %d\n", cur.step);
            return ;
        }
        if(vis[cur.x][cur.y][cur.statu])    continue;
        vis[cur.x][cur.y][cur.statu] = 1;
        for(int i = 0; i < 4; ++i) {
            int xx = cur.x + to[i][0];
            int yy = cur.y + to[i][1];
            if(xx < 1 || yy < 1 || xx > n || yy > m)    continue;
            if(mp[xx][yy] == '#') continue;
            if(cur.statu == 0 && mp[xx][yy] == 'd') continue;
            if(cur.statu == 1 && mp[xx][yy] == 'f') continue;
            q.push(node{xx, yy, cur.statu, cur.step + 1});
        }
        if(mp[cur.x][cur.y] == '*')
            q.push(node{cur.x, cur.y, !cur.statu, cur.step + 1});
    }
    puts("fei pigeon is ripe!");
    return ;
}

int main() {
    scanf("%d%d", &n, &m);
    node s, t;
    for(int i = 1; i <= n; ++i) {
        scanf("%s", mp[i] + 1);
        for(int j = 1; j <= m; ++j) {
            if(mp[i][j] == '@') {
                mp[i][j] = '.';
                s = node(i, j, 0, 0);
            }else if(mp[i][j] == '$') {
                mp[i][j] = '.';
                t = node(i, j, 0, 0);
            }
        }
    }
    bfs(s, t);

    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Guugle/p/12051556.html
今日推荐