題目:Fans and Gem遊戲(有點像2012,又不太一樣樣):在二維的迷宮(四周被墻包圍),
(迷宮裡面也有些地方是墻),迷宮中有三種寶石(Gem,用123表示)和飛碟(flyer);
每次遊戲操作可以選取一個方向,fans會吹動寶石和飛碟,使得他們以相同的速度運動:
1.寶石和飛碟,碰到墻或者其他停止的寶石或飛碟就停下來;
2.所有的寶石和飛碟停下后,如果寶石四周(上下左右)有相同顏色的寶石就一起消除;
3.剩下的寶石和飛碟,繼續唄fans吹動,到達新的穩定狀態;
4.持續進行2和3過程直到不能消除為止;
現在要求出最少的操作次數(最短的方向字符組成的串),長度相同時取字典序最小。
分析:搜索,模擬。利用bfs求最短路徑,每次利用dfs模擬消除過程。
模擬消除的過程:
1.模擬移動過程(從最近枚舉到最遠);
2.判斷是否可以消除,如果可以使用dfs消除(每次搜索四周,相同的數字變成‘ ’);
3.循環上述過程直到,沒有消除寶石即結束;
說明:題目開始看錯了,以為只是消除一次╮(╯▽╰)╭。
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <map>
using namespace std;
typedef struct _qnode {
int steps;
char command[22];
char maps[12][21];
}qnode;
void copy_map(char from[][21], char to[][21], int n, int m)
{
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < m; ++ j) {
to[i][j] = from[i][j];
}
}
}
string map_to_string(char Maps[][21], int n, int m)
{
string str(Maps[0]);
for (int i = 1; i < n; ++ i) {
str += string(Maps[i]);
}
return str;
}
int dxy[4][2] = {-1, 0, 0, -1, 0, 1, 1, 0};
void dfs(int x, int y, char c, char maps[][21])
{
if (maps[x][y] != c) {
return;
}
maps[x][y] = ' ';
for (int i = 0; i < 4; ++ i) {
dfs(x+dxy[i][0], y+dxy[i][1], c, maps);
}
}
int disappear(int n, int m, char maps[][21])
{
int flag = 0;
for (int x = 0; x < n; ++ x) {
for (int y = 0; y < m; ++ y) {
if (maps[x][y] >= '1' && maps[x][y] <= '3') {
for (int k = 0; k < 4; ++ k) {
if (maps[x][y] == maps[x+dxy[k][0]][y+dxy[k][1]]) {
dfs(x, y, maps[x][y], maps);
flag = 1;
break;
}
}
}
}
}
return flag;
}
int move(char maps[][21], int n, int m, int direction)
{
// 想把這4個合併,但是函數參數有點多
if (direction == 0) { // down
for (int j = 0; j < m; ++ j)
for (int i = n-1; i >= 0; -- i) {
if (maps[i][j] >= '1' && maps[i][j] <= '3' || maps[i][j] == '@') {
int position = i;
while (maps[position+1][j] == ' ') {
maps[position+1][j] = maps[position][j];
maps[position][j] = ' ';
position ++;
}
}
}
}else if (direction == 1) { // left
for (int i = 0; i < n; ++ i)
for (int j = 0; j < m; ++ j) {
if (maps[i][j] >= '1' && maps[i][j] <= '3' || maps[i][j] == '@') {
int position = j;
while (maps[i][position-1] == ' ') {
maps[i][position-1] = maps[i][position];
maps[i][position] = ' ';
position --;
}
}
}
}else if (direction == 2) { // right
for (int i = 0; i < n; ++ i)
for (int j = m-1; j >= 0; -- j) {
if (maps[i][j] >= '1' && maps[i][j] <= '3' || maps[i][j] == '@') {
int position = j;
while (maps[i][position+1] == ' ') {
maps[i][position+1] = maps[i][position];
maps[i][position] = ' ';
position ++;
}
}
}
}else if (direction == 3) { // up
for (int j = 0; j < m; ++ j)
for (int i = 0; i < n; ++ i) {
if (maps[i][j] >= '1' && maps[i][j] <= '3' || maps[i][j] == '@') {
int position = i;
while (maps[position-1][j] == ' ') {
maps[position-1][j] = maps[position][j];
maps[position][j] = ' ';
position --;
}
}
}
}
return disappear(n, m, maps);
}
int over(char state[][21], int n, int m)
{
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < m; ++ j) {
if (state[i][j] >= '1' && state[i][j] <= '3') {
return 0;
}
}
}
return 1;
}
qnode Q[200001];
char direction[4] = {'D', 'L', 'R', 'U'};
void bfs(int n, int m, char input[][21])
{
map <string, int> M;
int head = 0, tail = 1;
Q[0].steps = 0;
copy_map(input, Q[0].maps, n, m);
while (head < tail) {
qnode Now = Q[head ++];
if (over(Now.maps, n, m)) {
puts(Now.command);
return;
}
if (Now.steps > 18) {
puts("-1");
return;
}
qnode New = Now;
New.steps = Now.steps + 1;
for (int i = 0; i < 4; ++ i) {
copy_map(Now.maps, New.maps, n, m);
while(move(New.maps, n, m, i)); // 持續運動到不能消除
New.command[Now.steps] = direction[i];
New.command[New.steps] = 0;
string new_map = map_to_string(New.maps, n, m);
if (!M[new_map]) {
M[new_map] = 1;
Q[tail ++] = New;
}
}
}
puts("-1");
}
int main()
{
int T, N, M;
char input[13][21];
while (~scanf("%d",&T))
while (T --) {
scanf("%d%d",&N,&M);
getchar();
for (int i = 0; i <= N; ++ i) {
gets(input[i]);
}
bfs(N, M, input);
}
return 0;
}
相關數據:
20
9 8
########
## 1##
## 2 #
# 1 ##
##2 ##
# 1@##
### ##
#### ###
########
7 8
########
#212121#
# #
# # # ##
# # #
# ##
########
4 4
####
#1 #
#@2#
####
5 5
#####
#1 #
##@@#
#1 #
#####
5 14
##############
#@ 1 3 1@#
#@#2# # #
#213 @13 @3#
##############
9 9
#########
# 3 #
# 3 @ #
#21 1@ #
#3 3#
# 2 # @#
# # #
## 3 2 #
#########
11 13
#############
# 2 2@ # #
#2 3@ 1 @@ 2#
# 2 @2 #
#3 2 @ # 3 #
## 2# 2#
#3 1 #
## # 3 #
# # 1@# 1#
# 3#2 31 @##
#############
5 12
############
#3 @@ 2 1 3#
# 3 1#@ # #
# # 2 #
############
12 9
#########
# 12 #2#
# # 1#
# 3#
# 2#1#
#1312# #
# 2# #
# 2#
### 1 #
# 23#
#@ @ #
#########
7 20
####################
# ## 3# 1 23##
#3 @ 3 3 #
#1 3 1 #2 2 2 #
## # #1 1 #
# 2 #13@ 21#
####################
11 7
#######
## @#
# 2 @#
# 3#@#
#2# # #
# 3 2#
# ##
# 3 ##
#3@ ##
# # 2 #
#######
7 15
###############
# 1 12 # #
#3 #23231 3 #
# 2 # # 2 #
# # 123 3 1#
# 2# 1 @1##23#
###############
5 9
#########
# @1 #
# 3 ##
#1 31 #
#########
9 9
#########
# 1 1 #
#1 ####
# 2# 3 #
# 2 ##
#3 1 #
# 1 #
# 1@@ #
#########
10 7
#######
#1 1 #
# @ #
## 1 #
# #
#3# ##
# # #1#
# ###
# 1 3#
#######
7 11
###########
# 1#32##
# 2 3#
#@ @3 # #
# 2 #
#2 3 31#
###########
9 14
##############
# 2 12 #
# @ #
#1 #13 1@ #
# # # #
#2# # 2 3 #
## 3 2 @@##
# 1 21#
##############
8 18
##################
#### # ## 3#
#21 # 1 @@ @ ##
#3 @# 2 2 23#
# #1@ # # 1#
# 2 3#
#3 @ # #
##################
12 20
####################
# 2# # 2 1 3#
#1 @1 3 # #
#@2@1#@ @3#2# 2 #
# # 2 #
#3#1 @1 #
# 2 # @ 13 #
# 2 1##2@# #23#
#21 # 13 2 ##
# @ # ##
# # 1@ #@ 231 #
####################
11 7
#######
###1@2#
# 1 3 #
# # #
# 3@ #
# #
#23# @#
#32 #
#2 #
# 32 #
#######
相關輸出:
LURD
DL
-1
DRDLURD
RDLULRD
DRURDLDLURU
RLURULURDL
-1
RDLULURDLDRD
RDLDLURDRURD
LDRD
-1
-1
RDLDR
-1
LDRDLUL
RULDRDLDRUL
RDRULURDLD
RDLULRUL
DLUD