Sicily 1153. 马的周游问题 解题报告
1153_马的周游问题
题目链接:
题目大意:
给定一个8×8棋盘,格子标号1到64,输入一个初始位置的标号,按照马走“日”字的方法,找一条能刚好走完整个棋盘的路径,每个格子恰好只访问过一次。
思路:
用深度优先搜索的方法可以解决问题。首先用二维数组表示整个棋盘,直接用bool类型来表示棋盘的格子是否被访问过。由于输入的是格子的标号,要方便搜索这里用了Point类来表示格子,将序号转化为Point类型。成员ourDegree表示一个点的出度,即这个点可以访问到的下一个点的个数,用来在深搜的时候找出度最少的下一个点访问,这样可以节省时间。
dfs的返回类型是bool,表示是否已经找到解。参数count表示已经访问的点的个数,如果已经访问完棋盘则将记录在route[]里面的结果输出。
代码:
#include <iostream>
#include <algorithm>
#include <memory.h>
#include <vector>
using namespace std;
const int WIDTH = 8, HEIGHT = 8;
class Point {
public:
int x;
int y;
int outDegree;
};
int move_x[] = { -1, -1, -2, -2, 1, 1, 2, 2 };
int move_y[] = { -2, 2, 1, -1, 2, -2, 1, -1 };
bool visited[WIDTH + 2][HEIGHT + 2];
bool solved;
int route[WIDTH * HEIGHT];
void calculateXY(const int position, int &x, int &y);
bool dfs(Point p, int count);
bool comp(const Point &p1, const Point &p2);
bool isvalid(const Point &p);
int main() {
int startPosition;
Point p;
while (cin >> startPosition && startPosition != -1) {
solved = false;
memset(visited, false, sizeof(visited));
calculateXY(startPosition, p.x, p.y);
route[0] = startPosition;
visited[p.x][p.y] = true;
dfs(p, 1);
}
return 0;
}
void calculateXY(const int position, int &x, int &y) {
x = (position - 1) / 8 + 1;
y = position - ((x - 1) * 8);
}
bool dfs(Point p, int count){
//Pre: Given a Point and the count of Points that have been found.
//Post:If there is a route, print it and return true, else return false.
if(count == WIDTH * HEIGHT){//print route
cout << route[0];
for (int i = 1; i < WIDTH * HEIGHT; ++i) {
cout << " " << route[i];
}
cout << endl;
return true;
}
else{//从当前点可以访问到的点找到出度最小那个继续搜索
Point temp;
vector<Point>nexts;
for (int i = 0; i < 8; ++i) {
temp.x = p.x + move_x[i];
temp.y = p.y + move_y[i];
temp.outDegree = 0;
if(isvalid(temp)){
Point tempNext;
for (int j = 0; j < 8; ++j) {
tempNext.x = temp.x + move_x[j];
tempNext.y = temp.y + move_y[j];
if(isvalid(tempNext))
temp.outDegree++;
}
nexts.push_back(temp);
}
}
sort(nexts.begin(), nexts.end(), comp);//按照出度的大小排序,出度小的优先访问
for (unsigned int i = 0; i < nexts.size(); ++i) {
visited[nexts[i].x][nexts[i].y] = true;
route[count] = (nexts[i].x - 1) * WIDTH + nexts[i].y;
if(dfs(nexts[i], count + 1))
return true;
visited[nexts[i].x][nexts[i].y] = false;
}
return false;
}
}
bool comp(const Point &p1, const Point &p2){
return p1.outDegree < p2.outDegree;
}
bool isvalid(const Point &p){
//判断一个点是否可以访问
return (p.x >= 1 && p.x <= 8 && p.y >= 1 && p.y <= 8 && !visited[p.x][p.y]);
}

浙公网安备 33010602011771号