1153. 马的周游问题(DFS,优先选最少可走的点)

/*1152.马周游问题
 题目大意:从给定的一个位置出发,求出能够不重复地走遍棋盘中每个
           格子的一条路线。
 
 解题思路:1、对每个节点都有8个方向可走。 
           2、统计可走方向的下一步可走方向的数目,按从小到大排序
              则当前的节点优先选择具有较少下一步可走方向数据的节点
              访问
           3、对每个节点访问前,都将其状态标记为isVisit = true;
              然后开始访问他的下一个。 做完所有事情后,记得把
              状态isVisit = false。
           4、结束条件:当记录步数的数组的长度到达规定数目时,
              就停止访问,返回 
*/
#include <stdlib.h>
#include <iostream>
#include<algorithm>
using namespace std;
#define N 8
#define M 8
//定义八个方向的x和y坐标偏移量,放进数组 
int direction[8][2] ={{-1,2}, {-2,1}, {-2,-1}, {-1,-2},{1,-2}, {2,-1},{2,1},{1,2}};

int node[N][M];
bool isVisit[N][M];
//存放已经走过的节点 
int temp[N*M];
struct grid{
	int x;
	int y;
	int count;
};

bool cmp(grid a, grid b){
   return a.count < b.count;     
}

//获得(x,y)下一步可走的方向数目 
int getCount(int x, int y){
   int count = 0;
   	for (int i=0; i<8; i++) {
	    int xx = x + direction[i][0];
        int yy = y + direction[i][1];
	    if (xx>=0&&yy>=0&&xx<N&&yy<M&&!isVisit[xx][yy]) {
	        count++;
	    }
	}
    return count;    
}

//返回(x,y)下一步可走的方向数目,并且对(x,y)可走的下一步(假设为(xi,yi))中,
//对每个(xi,yi)的下一步可走方向数进行从小到大排序,放进数据grids[]中;也就是说
//当前(x,y)会优先选择具有最小下一步可走方向数的(xi,yi) 

int get_grid(grid grids[], int x,int y) {
       int n=0;
       
	for (int i=0; i<8; i++) {
	    int xx = x + direction[i][0];
           int yy = y + direction[i][1];
	    if (xx>=0&&yy>=0&&xx<N&&yy<M&&!isVisit[xx][yy]) {
		grids[n].x = xx;
		grids[n].y = yy;
		grids[n].count = getCount(xx, yy);
		n++;
	    }
	}
	sort(grids, grids + n, cmp);
	return n;
}

//进行深度搜索 
bool search(int x, int y, int k){
	    temp[k] = x*M + y +1;	
		//当遍历节点数到达规定数目时,输出结果,并返回,中止递归 
		if(k == N*M - 1){
			for(int i=0; i<= k; i++)
			cout << temp[i] << " ";
			return true;
		}
		isVisit[x][y] = true;
		grid grids[8];
		int n =get_grid(grids, x, y);
		//cout << n << endl;
		for(int i=0; i<n; i++){
			if(search(grids[i].x, grids[i].y, k+1))
					return true;
			
		}
		isVisit[x][y] = false;
		return false;
}


int main()
{ 
    int n;
	int v = 1;

	for(int i=0; i<N; i++){
			for(int k=0; k<M; k++){
				node[i][k] = v++;
			}
	}
	
	while(cin >> n && n != -1){
		for(int i=0; i<N; i++){
			for(int k=0; k<M; k++){
				isVisit[i][k] = false;
			}
		}
		int x = (n-1)/M;
		int y = (n-1) % M;
		
		search(x,y, 0);
	}
	
    system("pause");
    return 0;
}

    原文作者:骑士周游问题
    原文地址: https://blog.csdn.net/xiehaoyun2012/article/details/8459589
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞