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‘均不在最终需要到达的位置,且场景中至少有一个箱子
输出
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: 推箱子的主要内容,如果未能解决你的问题,请参考以下文章

zzulioj - 2597: 角谷猜想2

ZZULIOJ 1882: 蛤玮的魔法 (计算几何)

ZZULIOJ 1882: 蛤玮的魔法 (计算几何)

zzulioj - 2628: 小新的字母广场

zzulioj - 2624: 小H的奇怪加法

zzulioj-2115乘积最大(区间dp)