题目1 : 推箱子
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
推箱子是一款经典游戏。如图所示,灰色格子代表不能通过区域,蓝色方格是箱子,黑色圆形代表玩家,含有圆点的格子代表目标点。
规定以下规则:
一局游戏中只会有一个箱子,一个玩家和一个目标点。
通过方向键控制玩家移动。
图中的灰色格子代表墙壁,玩家与箱子都不能通过。
推到墙壁的箱子,就无法再将箱子推离墙壁,因为玩家无法到达箱子靠墙壁的一侧去推箱子。也就是说箱子只能以“被推”的方式被移动,不是以“被拉”的方式被移动。但如果玩家将箱子推至墙壁后,垂直墙壁的两侧没有阻碍物,则玩家可以朝这两个不同的方向推移箱子。如果箱子进入角落,就没有办法再推动这个箱子了。
玩家是不能走出场景的。玩家推着箱子到达场景边缘,如果继续点击使玩家和箱子向墙壁前进的方向键,箱子和人都会保持不动。玩家的前进方向上如果有墙壁,也是不能前进的。但是这些点击都视为合理的输入。
箱子一旦到达目标点,就不能再移动了。但这时,玩家仍然可以在场景内自由行动。如果继续尝试推箱子,那么玩家将会和箱子一起保持在原地不动。
现在,给出一种方向键的点击方案,请判断,这种方案是否能使箱子最终停在目标点上。为了方便表示,我们以0代表空白格子,以4代表不能通过区域,以1代表玩家,以3代表箱子,以2代表目标点。
输入
第一行数据包含三个整数,N,M,S。其中,N(0 < N <= 100)代表格子的宽度,M(0 < M <= 100)代表格子的高度,S(0 < S <= 200)代表测试点的个数。
接下来的M行,每行都会有N个字符,描述当前的盘面。
接下来的S行,每行都代表一个测试点。每行都以一个整数T(0 < T <= 10000)开头,接下来是一个空格和T个字符。这T个字符仅由d,u,l,r这四个字母组成,分别代表了敲击向下,向上,向左,向右的方向键。
输出
对于每个测试点,输出最后箱子是否在目标点上。如果是,输出YES,如果不是,则输出NO。
样例输入
5 4 3
00000
13000
00200
00000
4 rurd
6 urdldr
6 rrrurd
样例输出
YES
YES
NO
代码如下,已通过AC测试。
原创代码,请勿转载!
//
// Obeject.h
//
#include <vector>
#include <iostream>
using namespace std;
#ifndef PUSHBOX_OBJECT_H
#define PUSHBOX_OBJECT_H
struct coordinate
{
int x;//行标——M
int y;//列标--N
};
class Object
{
private:
// std::vector<std::vector<int >> coordinate;//多维vector的尝试
int chessboard[102][102];
int chessboard_backup[102][102];
int N, M, S;
coordinate player;//当前玩家坐标
coordinate playerNext;
coordinate player_backup;
coordinate box;//当前箱子坐标
coordinate boxNext;
coordinate box_backup;
coordinate target;
void move();
void down();
void up();
void left();
void right();
public:
Object();
void implement();
};
#endif //PUSHBOX_OBJECT_H
//
// Obeject.h
//
#include <sstream>
#include "Object.h"
void Object::move()
{
if (chessboard[playerNext.x][playerNext.y] == 4)
{
return;
} else if (chessboard[playerNext.x][playerNext.y] == 0
|| chessboard[playerNext.x][playerNext.y] == 2)
{
player.x = playerNext.x;
player.y = playerNext.y;
} else if (chessboard[playerNext.x][playerNext.y] == 3)//此为player遇到box
{
if (chessboard[boxNext.x][boxNext.y] == 4)
{
return;
} else if (chessboard[boxNext.x][boxNext.y] == 0)
{
chessboard[box.x][box.y] =0;
player.x = playerNext.x;
player.y = playerNext.y;
box.x = boxNext.x;
box.y = boxNext.y;
chessboard[box.x][box.y] =3;
} else if (chessboard[boxNext.x][boxNext.y] == 2)
{
chessboard[box.x][box.y] =0;
player.x = playerNext.x;
player.y = playerNext.y;
box.x = boxNext.x;
box.y = boxNext.y;
chessboard[box.x][box.y] = 4;//到达目标box不动;
} else
{
cout << "其他情况!检测1";
return;
}
} else
{
cout << "其他情况!检测2";
return;
}
}
void Object::up()
{
playerNext.x = player.x - 1;
playerNext.y = player.y;
boxNext.x = box.x - 1;
boxNext.y = box.y;
move();
}
void Object::down()
{
playerNext.x = player.x + 1;
playerNext.y = player.y;
boxNext.x = box.x + 1;
boxNext.y = box.y;
move();
}
void Object::left()
{
playerNext.x = player.x;
playerNext.y = player.y - 1;
boxNext.x = box.x;
boxNext.y = box.y - 1;
move();
}
void Object::right()
{
playerNext.x = player.x;
playerNext.y = player.y + 1;
boxNext.x = box.x;
boxNext.y = box.y + 1;
move();
}
void Object::implement()
{
cin >> N;
cin >> M;
cin >> S;
char c;
for (int i = 1; i <= M; ++i)
{
for (int j = 1; j <= N; ++j)
{
cin >> c;
chessboard_backup[i][j] = c - '0';
if (chessboard_backup[i][j] == 1)
{
player_backup.x = i;
player_backup.y = j;
chessboard_backup[i][j] = 0;
}
if (chessboard_backup[i][j] == 2)
{
target.x = i;
target.y = j;
}
if (chessboard_backup[i][j] == 3)
{
box_backup.x = i;
box_backup.y = j;
}
}
}
for (int k = 0; k < S; ++k)
{
memcpy(chessboard,chessboard_backup,sizeof(chessboard_backup));
player=player_backup;
box=box_backup;
int l;
cin >> l;
char s;
for (int i = 0; i < l; ++i)
{
cin >> s;
switch (s)
{
case 'u':
{
up();
break;
}
case 'd':
{
down();
break;
}
case 'l':
{
left();
break;
}
case 'r':
{
right();
break;
}
default:
{
cout << "switch出错!出现非指定字符!";
}
}
}
(box.x == target.x && box.y == target.y) ? cout << "YES\n" : cout << "NO\n";
}
}
Object::Object()
{
for (int i = 0; i < 102; ++i)
{
for (int j = 0; j < 102; ++j)
{
chessboard_backup[i][j]=4;
}
}
}
#include "Object.h"
int main()
{
Object a;
a.implement();
return 0;
}