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

题目链接

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

时间限制 内存限制
1 Sec 128 MB

竟然有自己的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..
[email protected]#..
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;
}

原文地址:https://www.cnblogs.com/Guugle/p/12051556.html

时间: 2024-10-22 13:58:11

FJNU2019第二次友谊赛-红烧非鸽肉[bfs]的相关文章

fjnu2019第二次友谊赛 B题

### 题目链接 ### 题目大意: 给你一个 n * m 的地图以及小蛇蛇头的初始位置,告诉你它会往 上.下.左.右 四个方向走.若在走的过程中(包括结束时)会使得小蛇越界,则输出 "Game Over!" ,否则输出 "Alice!" 以及蛇头最后的坐标位置. 分析: 简单模拟题,只需模拟小蛇蛇头的运动方向,看它是否会在运动的过程中(包括结束时)死掉.若死掉则直接退出模拟并输出 "Game Over!" 即可. 代码如下: #include&

JS第二天

今天是我们学习JS的第二天,我们开始学习各种语句了. 第一:我们学了If  else-if 语句,要知道他执行的过程. If(判断条件){  一般是boolean类型的值或是关系表达式或是逻辑表达式 要执行的代码; }else if(判断条件){ 要执行的代码; }else if(判断条件){ 要执行的代码; }...else { 要执行的代码; } 第二:三元运算符,像一些简单的语句,我们要学会用三元运算符来写,这样看上去更简洁.他的写法是: 表达式1(关系表达式或是逻辑表达式)? 表达式2:

递归与非递归及其相互转换

一.什么是递归 递归是指某个函数直接或间接的调用自身.问题的求解过程就是划分成许多相同性质的子问题的求解,而小问题的求解过程可以很容易的求出,这些子问题的解就构成里原问题的解了. 二.递归的几个特点 1.递归式,就是如何将原问题划分成子问题. 2.递归出口,递归终止的条件,即最小子问题的求解,可以允许多个出口. 3.界函数,问题规模变化的函数,它保证递归的规模向出口条件靠拢 三.递归的运做机制 很明显,很多问题本身固有的性质就决定此类问题是递归定义,所以递归程序很直接算法程序结构清晰.思路明了.

【LeetCode-面试算法经典-Java实现】【144-Binary Tree Preorder Traversal(二叉树非递归前序遍历)】

[144-Binary Tree Preorder Traversal(二叉树非递归前序遍历)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Given a binary tree, return the preorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3}, 1 2 / 3 return [1,2,3]. Note: Recursive solution

【LeetCode-面试算法经典-Java实现】【145-Binary Tree Postorder Traversal(二叉树非递归后序遍历)】

[145-Binary Tree Postorder Traversal(二叉树非递归后序遍历)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3}, 1 2 / 3 return [3,2,1]. Note: Recursive soluti

基础篇-在非UI线程中更新UI元素

个人原创,转载请注明出处: http://blog.csdn.net/supluo/article/details/ 先了解两个概念 1.UI:User Interface的缩写,用户界面的意思.你可以不恰当的理解为我们能够看到的,操作的东西:在Android中什么才称为UI呢,可以简单的理解为View及其子类等元素.这是一个不够正确的概念,只是对新手做一个简单的抛砖引玉. 2.ANR:Application Not Responding,意思是程序没有响应. 在如下情况下,Android会报出

历届试题 青蛙跳杯子-(bfs)

题目:http://lx.lanqiao.cn/problem.page?gpid=T448 题意:有两个字符串例如*WWBB和WWBB*,*每次能往左或右跳1-3步,与原位置的字符交换,问最少步数跳到第二个字符串的状态.bfs裸题,C++能秒杀,改用java做题倒是折腾了挺久,测试了HashMap和LinkedList的用法,第一次提交超时,看别人代码后修正. import java.util.HashMap; import java.util.LinkedList; import java.

小非大人说·华为云——弹性负载均衡器ELB

小非大人说·华为云--弹性负载均衡器ELB小非大人:工程师小闲大人:售前小年大人:老板 小闲大人说,熊迪,一客户说今天要配置弹性云负载均衡器ELB,去支持下,熊迪. 其实我想和小闲大人说,可不可以不做你的熊迪,吃饭又不叫我,算了,不吃饭, 补下负载均衡内容,亲们一提起负载均衡,要么Citrix netscalar,F5-BIG-LTM/GTM等大佬产品,那么华为云的ELB和它们功能一样,优点是稳定,简单,易上手,容易等.先上拓扑图为敬 第一部分-配置选购第二部分-实践场景第三部分-价格说明备注:

MySQL中Innodb的聚簇索引和非聚簇索引

聚簇索引 数据库表的索引从数据存储方式上可以分为聚簇索引和非聚簇索引(又叫二级索引)两种.Innodb的聚簇索引在同一个B-Tree中保存了索引列和具体的数据,在聚簇索引中,实际的数据保存在叶子页中,中间的节点页保存指向下一层页面的指针.“聚簇”的意思是数据行被按照一定顺序一个个紧密地排列在一起存储.一个表只能有一个聚簇索引,因为在一个表中数据的存放方式只有一种. 一般来说,将通过主键作为聚簇索引的索引列,也就是通过主键聚集数据.下图展示了Innodb中聚簇索引的结构(图片来自<高性能MySQL