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