一個 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