UVa 10274 - Fans and Gems

題目: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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值