#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int n, p, q;
int used[26][26];
int pathX[26];
int pathY[26];
int dir[8][2] = { { -2, -1 }, { -2, 1 }, { -1, -2 }, { -1, 2 }, { 1, -2 }, { 1,
2 }, { 2, -1 }, { 2, 1 } };
int ok;
void dfs(int x, int y, int step) {
pathX[step - 1] = x;
pathY[step - 1] = y;
used[x][y] = 1;
if (step == p * q) {
ok = 1;
return;
}
int i;
for (i = 0; i < 8; i++) {
int _x = x + dir[i][0];
int _y = y + dir[i][1];
if (_x >= 0 && _y >= 0 && _x < q && _y < p && !used[_x][_y]) {
used[_x][_y] = 1;
dfs(_x, _y, step + 1);
used[_x][_y] = 0;
}
}
}
int main() {
int sum = 0;
cin >> n;
while (n--) {
cin >> p >> q;
ok = 0;
memset(used, 0, sizeof(used));
memset(pathX, 0, sizeof(pathX));
memset(pathY, 0, sizeof(pathY));
printf("Scenario #%d:\n", ++sum);
dfs(0, 0, 1);
if (ok != 1) {
printf("impossible\n");
} else {
for (int i = 0; i < p * q; i++) {
printf("%c%d", pathX[i] + 'A', pathY[i] + 1);
}
printf("\n");
}
printf("\n");
}
return 0;
}
你的算法理解没有什么问题,可能是有点粗心了。
1:dfs中if (_x >= 0 && _y >= 0 && _x < q && _y < p && !used[_x][_y]) 写错了应该是:
if (_x >= 0 && _y >= 0 && _x < p && _y < q && !used[_x][_y])
2:输出的时候 printf("%c%d", pathX[i] + 'A', pathY[i] + 1);写错了,Y轴是字母,X轴是数字,应该是:
printf("%c%d", pathY[i] + 'A', pathX[i] + 1);
修改之后还是WA,下面的结果显然和所给的不一样
5
4 3
Scenario #1:
A1B3C1A2B4C2A3C4B2A4C3B1
5 5
Scenario #2:
A1B3C5E4C3D5B4D3E5C4A5C2D4B5A3B1D2A2B2A4C1A2E1A4A5
@informatics:
嗯,还有一个问题:
if (_x >= 0 && _y >= 0 && _x < q && _y < p && !used[_x][_y]) {
used[_x][_y] = 1;
dfs(_x, _y, step + 1);
used[_x][_y] = 0;
}
上面设置used[_x][_y] = 1;是多余的,因为所有的访问在外层访问的时候都已经标记了。
如果从dfs退出,说明这一步走的不对,退回上一步,同时在最后设置used[x][y] = 0;
整理后的代码:
#include "stdafx.h"
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int n, p, q;
int used[26][26];
int pathX[26];
int pathY[26];
int dir[8][2] = { { -2, -1 }, { -2, 1 }, { -1, -2 }, { -1, 2 }, { 1, -2 }, { 1,
2 }, { 2, -1 }, { 2, 1 } };
int ok;
void dfs(int x, int y, int step) {
pathX[step - 1] = x;
pathY[step - 1] = y;
used[x][y] = 1;
if (step == p * q) {
ok = 1;
return;
}
int i;
for (i = 0; i < 8; i++) {
int _x = x + dir[i][0];
int _y = y + dir[i][1];
if (_x >= 0 && _y >= 0 && _x < p && _y < q && !used[_x][_y]) {
dfs(_x, _y, step + 1);
}
}
used[x][y] = 0;
}
int main() {
int sum = 0;
cin >> n;
while (n--) {
cin >> p >> q;
ok = 0;
memset(used, 0, sizeof(used));
memset(pathX, 0, sizeof(pathX));
memset(pathY, 0, sizeof(pathY));
printf("Scenario #%d:\n", ++sum);
dfs(0, 0, 1);
if (ok != 1) {
printf("impossible\n");
} else {
for (int i = 0; i < p * q; i++) {
printf("%c%d", pathY[i] + 'A', pathX[i] + 1);
}
printf("\n");
}
printf("\n");
}
return 0;
}
@informatics:
if (_x >= 0 && _y >= 0 && _x < q && _y < p && !used[_x][_y]) {
used[_x][_y] = 1;
dfs(_x, _y, step + 1);
used[_x][_y] = 0;
}
对于当前位置x,y,首先设置访问标记为1,然后以当前位置为起点,8个方向搜索,如果在搜索过程中发现当前的step和格子数目相等说明成功;如果从当前位置搜索8个方向后发现step和格子数目不相等,说明当前这个搜索方向不对,则这只当前的访问标记为0,退回去,进行下一个方向的搜索。
你的for里面没有必要对下一个访问方向设置访问标记位,因为下面进行dfx的时候会进行标记位的设置。所以应该在最后设置
used[x][y] = 0;。
@informatics:
@informatics: 你的代码修改之后执行:点这里
@Wang Hui: 谢谢。。。。。