zzulioj - 2616: 推箱子
Posted shuitiangong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了zzulioj - 2616: 推箱子相关的知识,希望对你有一定的参考价值。
题目链接:http://acm.zzuli.edu.cn/problem.php?id=2616
题目描述
玩了自己设计的游戏,VX觉得更更更无聊了。。。于是决定玩一把惊险刺激,热血沸腾的推箱子游戏。 游戏规则如下: 给出游戏场景的N(表示共有N行),M(表示共有M列),并给出N行M列的游戏场景图。 其中‘B’表示箱子的位置,‘#’表示墙,‘V’表示人物起始位置,‘E’表示空地,‘+’表示最终箱子需要到达的位置(该位置也为空地) 之后给出一串VX的行动记录,请帮忙算出最终是否能达成目标(及所有‘B’到达‘+’的位置) 其中U表示向上走,D表示向下走,L表示向左走,R表示向右走 若行走的方向是空地,则可以移动一格 若行走的方向是墙,则保持原位不动(及本次行动无效) 若行走方向是箱子,且箱子的同方向上是空地,则可以被移动,VX和箱子均移动一格 若行走方向是箱子,且箱子的同方向上是墙或者箱子,则无法被移动,则VX和箱子均不动(及本次行动无效)
输入
多实例
输入T,表示共有T组数据(T=10)
对于每组数据:
输入N(表示共有N行)M(表示共有M列)(3<=N<=20, 3<=M<=20)
接下来N行,每行M列给出场景图
接着给出VX的行动记录(行动次数不超过100,且至少行动一次)
输入数据保证场景图四周都是墙,且保证‘B’的数量与‘+’的数量一致,且初始状态下所有‘B‘均不在最终需要到达的位置,且场景中至少有一个箱子
输入T,表示共有T组数据(T=10)
对于每组数据:
输入N(表示共有N行)M(表示共有M列)(3<=N<=20, 3<=M<=20)
接下来N行,每行M列给出场景图
接着给出VX的行动记录(行动次数不超过100,且至少行动一次)
输入数据保证场景图四周都是墙,且保证‘B’的数量与‘+’的数量一致,且初始状态下所有‘B‘均不在最终需要到达的位置,且场景中至少有一个箱子
输出
VX能否将箱子全部推到指定位置,若能输出”Legendary”,若不能输出”Loser”。
注意,输出不含引号
注意,输出不含引号
样例输入 Copy
3
5 5
#####
#+EE#
#BEE#
#VB+#
#####
RLU
3 10
##########
#VEEEBEE+#
##########
RRRLLLRRRRRRRRRRR
7 7
#######
#EEB+E#
#E###E#
#E#V#E#
#E###E#
#EEEEE#
#######
UDLRUDLRUDLR
样例输出 Copy
Legendary Legendary Loser
模拟就行了
#include<set> #include<map> #include<stack> #include<queue> #include<cmath> #include<cstdio> #include<cctype> #include<string> #include<vector> #include<climits> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define max(a, b) (a > b ? a : b) #define min(a, b) (a < b ? a : b) #define mst(a) memset(a, 0, sizeof(a)) #define _test printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ") using namespace std; typedef long long ll; typedef pair<int, int> P; const double eps = 1e-7; const int INF = 0x3f3f3f3f; const ll ll_INF = 233333333333333; const int maxn = 1e3+10; char _map[maxn][maxn]; struct pp{ int a, b; }point, Case[maxn]; int m, n, kase; void input() { kase = 0; scanf("%d%d", &n, &m); getchar(); for(int i=0;i<n;i++) scanf("%s",_map[i]); for (int i = 0; i<n; ++i) for (int j = 0; j<m; ++j) { if (_map[i][j] == ‘V‘) point.a = i, point.b = j; else if (_map[i][j] == ‘+‘) {//存入终点信息 并把+改成E简化判断 Case[kase].a = i, Case[kase].b = j; ++kase; _map[i][j] = ‘E‘; } } } void checker() { //检查读入数据处理情况 _test; for (int i = 0; i<n; ++i) for (int j = 0; j<m; ++j) printf(j == m-1 ? "%c " : "%c", _map[i][j]); } void checker2(){ //检查终点信息存入情况 _test; for (int i = 0; i<kase; ++i) printf("%d %d ", Case[i].a, Case[i].b); } void move() { char od[maxn]; scanf("%s%*c", od); int len = strlen(od); for (int i = 0; i<len; ++i) { if (od[i] == ‘U‘ && point.a-1 > 0 && _map[point.a-1][point.b] != ‘#‘) { //先判断移动的位置会不会越界 if (_map[point.a-1][point.b] == ‘E‘) { //判断上方是否为空地 swap(_map[point.a-1][point.b], _map[point.a][point.b]); --point.a; } else if (_map[point.a-1][point.b] == ‘B‘ && point.a-2 > 0 && _map[point.a-2][point.b] == ‘E‘) { //判断上方是否为箱子&&箱子能不能移动 swap(_map[point.a-2][point.b], _map[point.a-1][point.b]); swap(_map[point.a-1][point.b], _map[point.a][point.b]); --point.a; } } else if (od[i] == ‘D‘ && point.a+1 < n-1 && _map[point.a+1][point.b] != ‘#‘) { //同上 if (_map[point.a+1][point.b] == ‘E‘) { swap(_map[point.a+1][point.b], _map[point.a][point.b]); ++point.a; } else if (_map[point.a+1][point.b] == ‘B‘ && point.a+2 < n-1 && _map[point.a+2][point.b] == ‘E‘) { //下方 swap(_map[point.a+2][point.b], _map[point.a+1][point.b]); swap(_map[point.a+1][point.b], _map[point.a][point.b]); ++point.a; } } else if (od[i] == ‘L‘ && point.b-1 > 0 && _map[point.a][point.b-1] != ‘#‘) { //同上 if (_map[point.a][point.b-1] == ‘E‘) { swap(_map[point.a][point.b-1], _map[point.a][point.b]); --point.b; } else if (_map[point.a][point.b-1] == ‘B‘ && point.b-2 > 0 && _map[point.a][point.b-2] == ‘E‘) { //左边 swap(_map[point.a][point.b-2], _map[point.a][point.b-1]); swap(_map[point.a][point.b-1], _map[point.a][point.b]); --point.b; } } else if (od[i] == ‘R‘ && point.b+1 < m-1 && _map[point.a][point.b+1] != ‘#‘) { //同上 if (_map[point.a][point.b+1] == ‘E‘) { swap(_map[point.a][point.b+1], _map[point.a][point.b]); ++point.b; } else if (_map[point.a][point.b+1] == ‘B‘ && point.b+2 < m-1 && _map[point.a][point.b+2] == ‘E‘) { //右边 swap(_map[point.a][point.b+2], _map[point.a][point.b+1]); swap(_map[point.a][point.b+1], _map[point.a][point.b]); ++point.b; } } //checker(); 调试 //checker2(); 同上 } } bool ok() { for(int i = 0; i<kase; ++i) if (_map[Case[i].a][Case[i].b] != ‘B‘) //检查每个终点 return false; return true; } int main(void) { int t; scanf("%d%*c", &t); while(t--) { input(); move(); printf(ok() ? "Legendary " : "Loser "); } return 0; }
以上是关于zzulioj - 2616: 推箱子的主要内容,如果未能解决你的问题,请参考以下文章