趣味算法-0的迷宮

一個 5*5的矩陣,其中包含0-24 25個數字,數字在矩陣中沒有順序,其中0比較特殊,它可以和上下左右不同的數字進行交換,但一定在矩陣的範圍內。

0和上面的元素交換可以用 "U"表示;

0和下面的元素交換可以用 "D"表示;

0和左面的元素交換可以用 "L"表示;

0和右面的元素交換可以用 "R"表示;


舉例:
[20, 18, 7, 19, 10
 24, 4, 15, 11, 9
 13, 0, 22, 12, 14
 23, 16, 1, 2, 5
 21, 17, 8, 3, 6]

當執行完序列 “URRDDL”後,新的矩陣如下:

[20, 18, 7, 19, 10
 24, 15, 11, 12, 9
 13, 4, 22, 2, 14
 23, 16, 0, 1, 5
 21, 17, 8, 3, 6]


現在輸入一原始矩陣,給定一輸出矩陣,請給出執行0和上下左右交換的序列,看是否能從原始矩陣變換爲新的矩陣,如果無法達到要求,請輸出None.

例如:

輸入矩陣:

[20, 18, 7, 19, 10
 24, 4, 15, 11, 9
 13, 0, 22, 12, 14
 23, 16, 1, 2, 5
 21, 17, 8, 3, 6]

輸出矩陣:
[20, 18, 7, 19, 10
 24, 15, 11, 12, 9
 13, 4, 22, 2, 14
 23, 16, 0, 1, 5
 21, 17, 8, 3, 6]

執行完程序後得到序列 “URRDDL”


問題分析:

可以將問題轉換爲一個圖的問題。將兩個矩陣進行比較,如果同一位置上數字相同,則在一個新生成的比較矩陣中置0,如果不同,則置1。得到一個只有0和1的矩陣。遍歷這個矩陣,看所有的1是不是可以連在一起,並且記錄下遍歷的順序。


程序示例:


#include <iostream>

using namespace std;


void calculateTheRightSequence(int originalMatrix[][5], int newMatrix[][5],
                               char inputSequence[], char outputSequence[])
{
    static int steps = 0;
    static int move_map[5][5];
    static bool find = false;

    static int pos0_x = 0, pos0_y = 0;
    static int diff_cnt = 0;

    int cnt = 0;
    int swap_value;

    int i = 0, j = 0;
    if ( steps >= 15)
    {
        find = false;
        return;
    }

    if (steps == 0)
    {
        memset(move_map, 0, sizeof(int)*5*5);

        for (i = 0; i < 5; i++)
            for (j = 0; j < 5; j++)
            {
                if (originalMatrix[i][j] != newMatrix[i][j])
                {
                    move_map[i][j] = 1;
                    diff_cnt++;
                }
                if (originalMatrix[i][j] == 0)
                {
                    pos0_x = i;
                    pos0_y = j;
                }
            }
    }

    for (i = 0; i < 5; i++)
        for (j = 0; j < 5; j++)
        {
            if (originalMatrix[i][j] != newMatrix[i][j])
            {
                move_map[i][j] = 1;
                cnt++;
            }
        }

    cout << pos0_x << ":" << pos0_y << endl;
    for (i = 0; i < 5; i++)
    {
        for (j = 0; j < 5; j++)
        {
            cout << move_map[i][j] << " ";
        }
        cout << endl;
    }

    cout << endl;

    if ((cnt >= diff_cnt) && (steps > 0))
    {
        find = false;
        return;
    }

    if ((cnt == 0) && (steps < 14))
    {
        find = true;
        steps++;

        for (i = 1; i < steps; i++)
        {
            cout <<outputSequence[i];
        }
        cout << endl;
        return;
    }

    if (!find)
    {
        if ((pos0_x-1>=0) && (pos0_x-1< 5) && (move_map[pos0_x-1][pos0_y] == 1))
        {
            steps++;
            outputSequence[steps] = 'U';

            swap_value = originalMatrix[pos0_x][pos0_y];
            originalMatrix[pos0_x][pos0_y] = originalMatrix[pos0_x-1][pos0_y];
            originalMatrix[pos0_x-1][pos0_y]=swap_value;

            move_map[pos0_x][pos0_y] = 0;
            pos0_x = pos0_x - 1;

            calculateTheRightSequence(originalMatrix, newMatrix, inputSequence, outputSequence);

            if (!find)
            {
                outputSequence[steps] = 0;

                pos0_x = pos0_x + 1;
                move_map[pos0_x][pos0_y] = 1;
                swap_value = originalMatrix[pos0_x-1][pos0_y];
                originalMatrix[pos0_x-1][pos0_y] = originalMatrix[pos0_x][pos0_y];
                originalMatrix[pos0_x][pos0_y] = swap_value;

                steps--;
            }
        }

        if ((pos0_x+1>=0) && (pos0_x+1< 5) && (move_map[pos0_x+1][pos0_y] == 1))
        {
            steps++;
            outputSequence[steps] = 'D';

            swap_value = originalMatrix[pos0_x][pos0_y];
            originalMatrix[pos0_x][pos0_y] = originalMatrix[pos0_x+1][pos0_y];
            originalMatrix[pos0_x+1][pos0_y]=swap_value;
            move_map[pos0_x][pos0_y] = 0;
            pos0_x = pos0_x + 1;

            calculateTheRightSequence(originalMatrix, newMatrix, inputSequence, outputSequence);

            if (!find)
            {
                outputSequence[steps] = 0;

                pos0_x = pos0_x - 1;
                move_map[pos0_x][pos0_y] = 1;
                swap_value = originalMatrix[pos0_x+1][pos0_y];
                originalMatrix[pos0_x+1][pos0_y] = originalMatrix[pos0_x][pos0_y];
                originalMatrix[pos0_x][pos0_y] = swap_value;

                steps--;
            }
        }

        if ((pos0_y-1 >= 0) && (pos0_y-1< 5) && (move_map[pos0_x][pos0_y-1] == 1))
        {
            steps++;
            outputSequence[steps] = 'L';

            swap_value = originalMatrix[pos0_x][pos0_y];
            originalMatrix[pos0_x][pos0_y] = originalMatrix[pos0_x][pos0_y-1];
            originalMatrix[pos0_x][pos0_y-1]=swap_value;
            move_map[pos0_x][pos0_y] = 0;
            pos0_y = pos0_y-1;

            calculateTheRightSequence(originalMatrix, newMatrix, inputSequence, outputSequence);

            if (!find)
            {
                outputSequence[steps] = 0;

                pos0_y = pos0_y + 1;
                move_map[pos0_x][pos0_y] = 1;
                swap_value = originalMatrix[pos0_x][pos0_y];
                originalMatrix[pos0_x+1][pos0_y] = originalMatrix[pos0_x][pos0_y];
                originalMatrix[pos0_x][pos0_y] = swap_value;

                steps--;
            }
        }

        if ((pos0_y+1>=0) && (pos0_y+1< 5) && (move_map[pos0_x][pos0_y+1] == 1))
        {
            steps++;
            outputSequence[steps] = 'R';

            swap_value = originalMatrix[pos0_x][pos0_y];
            originalMatrix[pos0_x][pos0_y] = originalMatrix[pos0_x][pos0_y+1];
            originalMatrix[pos0_x][pos0_y+1]=swap_value;
            move_map[pos0_x][pos0_y] = 0;
            pos0_y = pos0_y+1;

            calculateTheRightSequence(originalMatrix, newMatrix, inputSequence, outputSequence);

            if (!find)
            {
                outputSequence[steps] = 0;

                pos0_y = pos0_y - 1;
                move_map[pos0_x][pos0_y] = 1;
                swap_value = originalMatrix[pos0_x][pos0_y];
                originalMatrix[pos0_x][pos0_y] = originalMatrix[pos0_x][pos0_y+1];
                originalMatrix[pos0_x][pos0_y+1]=swap_value;

                steps--;
            }
        }
    }

    if ((steps == 0) && (!find))
    {
        cout << "None" << endl;
    }
}


int main()
{
    int original[5][5] = {{20, 18, 7, 19, 10},
                          {24, 4, 15, 11, 9},
                          {13, 0, 22, 12, 14},
                          {23, 16, 1, 2, 5},
                          {21, 17, 8, 3, 6}};


    int newMatrix[5][5] = {{20, 18, 7, 19, 10},
                           {24, 15, 11, 12, 9},
                           {13, 4, 22, 2, 14},
                           {23, 16, 0, 1, 5},
                           {21, 17, 8, 3, 6}};

    char inputOperation[100]={0};
    char outputOperation[100]= {0};
    int a = 0;

    calculateTheRightSequence(original, newMatrix, inputOperation, outputOperation);

    cin >> a;
    return 0;
}

測試結果:

2:1
0 0 0 0 0
0 1 1 1 0
0 1 0 1 0
0 0 1 1 0
0 0 0 0 0


1:1
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
0 0 1 1 0
0 0 0 0 0


1:2
0 0 0 0 0
0 0 1 1 0
0 0 0 1 0
0 0 1 1 0
0 0 0 0 0


1:3
0 0 0 0 0
0 0 0 1 0
0 0 0 1 0
0 0 1 1 0
0 0 0 0 0


2:3
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0
0 0 1 1 0
0 0 0 0 0


3:3
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 1 1 0
0 0 0 0 0


3:2
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0


URRDDL






發佈了235 篇原創文章 · 獲贊 31 · 訪問量 59萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章