您的位置:首页 > 其它

趣味算法-0的迷宫

2016-03-07 20:14 337 查看
一个 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: