题目:
以下列方式向 5*5 矩阵中填入数字。设数字i(1=
1)(E, W)=(x±3,y)
2)(E, W)=(x,y±3)
3)(E, W)=(x±2,y±2)
求解问题如下:
编写一个程序,当数字1被指定于某个起始位置时,列举出其它24个数字应在的位置;列举该条件下的所有可能方案。
看到题目然后想到了之前马走日的做法,感觉很类似,就照着那个思路写下去了。
原理:回溯法
#include
using namespace std;
int N = 5;
int box[5][5];
int method = 0;
//打印方案
void read(int box[5][5]) {
cout << "方案" << ++method << endl;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++)
printf("%4d", box[i][j]);
cout << endl;
}
cout << endl;
}
//判断传进去的位置是否合法
bool IsLegal(int x, int y) {
if (x >= 0 && x < 5 && y >= 0 && y < 5 && box[x][y] == 0) return true;
else return false;
}
//递归存放数字
void walk(int x, int y, int n) {
box[x][y] = ++n; //设置当前位置上的数字
if (n == 25) { //完成了所有数字的填写
read(box);
box[x][y] = 0;
return;
}
if (IsLegal(x + 3, y)) walk(x + 3, y, n);//23
if (IsLegal(x - 3, y)) walk(x - 3, y, n);//21
if (IsLegal(x, y + 3)) walk(x, y + 3, n);//22
if (IsLegal(x, y - 3)) walk(x, y - 3, n);
if (IsLegal(x + 2, y + 2)) walk(x + 2, y + 2, n);
if (IsLegal(x + 2, y - 2)) walk(x + 2, y - 2, n);//20
if (IsLegal(x - 2, y + 2)) walk(x - 2, y + 2, n);
if (IsLegal(x - 2, y - 2)) walk(x - 2, y - 2, n);//24
box[x][y] = 0;//返回前,去除该位置上的数字
}
int main() {
cout << "请输入1的位置,从(1,1)-(5,5)中选择:" << endl;
int x, y;
cin >> x >> y;
walk(x-1, y-1, 0);
return 0;
}