[贪心+深搜]马的回路

[题目来源 POJ ]

输入就是棋盘的规格;W和H

翻译下面的文字,就是要找到一条 马(象棋玩过吧)的回路,然后将最小的路径输出(字典序),否则就输出‘impossible’;



Background
The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey
around the world. Whenever a knight moves, it is two squares in one direction and one square perpendicular to this. The world of a knight is the chessboard he is living on. Our knight lives on a chessboard that has a smaller area than a regular 8 * 8 board, but it is still rectangular. Can you help this adventurous knight to make travel plans?

Problem
Find a path such that the knight visits every square once. The knight can start and end on any square of the board. 输入 The input begins with a positive integer n in the first line. The following lines contain n test cases. Each test case consists of a single line with two positive integers p and q, such that 1 <= p * q <= 26. This represents a p * q chessboard, where p describes how many different square numbers 1, . . . , p exist, q describes how many different square letters exist. These are the first q letters of the Latin alphabet: A, . . . 输出 The output for every scenario begins with a line containing "Scenario #i:", where i is the number of the scenario starting at 1. Then print a single line containing the lexicographically first path that visits all squares of the chessboard with knight moves followed by an empty line. The path should be given on a single line by concatenating the names of the visited squares. Each square name consists of a capital letter followed by a number.
If no such path exist, you should output impossible on a single line.

[思路]:

贪心算法解决字典序的问题,贪心主要是一种思路。

深度搜索完成寻找,用带bool 类型完成搜索

代码如下,有什么疑问可以评论

#include <iostream>
#include <cstring>
using namespace std;
//马的周游 
int W,H,depth;
int a[9][9];
bool visited[9][9];
string path[65];//记录每一个路径 
//Dfs(x,y)表示,从x,y开始有一条马的回路 
bool Dfs(int x,int y){//第x行,第y列 
	if (visited[x][y])//如果x,y都已经走过了,就直接跳过 
		return false;
	visited[x][y]=true;//标记走过 
	string sx,sy;
	sx.push_back('A'+x);
	sy.push_back('1'+y); 
	path[depth++]=(sx+sy);//path记录路径
	if (depth==W*H)
		return true; 
	//depth表示走了多少个点,映射到深度 
	//字典序,用贪心的思维处理,就先检查最下的那个位置能不能走
	//按照贪心的思路进行排序,那么就可以完成了遍历 
	if(x-2>=0&&y-1>=0&&Dfs(x-2,y-1))return true;
	if(x-2>=0&&y+1<W&&Dfs(x-2,y+1))return true;
	if(x-1>=0&&y-2>=0&&Dfs(x-1,y-2))return true;
	if(x-1>=0&&y+2<W&&Dfs(x-1,y+2))return true;
	if(x+1<H&&y-2>=0&&Dfs(x+1,y-2))return true;
	if(x+1<H&&y+2<W&&Dfs(x+1,y+2))return true;
	if(x+2<H&&y-1>=0&&Dfs(x+2,y-1))return true;
	if(x+2<H&&y+1<W&&Dfs(x+2,y+1))return true;
	visited[x][y]=false;
	--depth;
	return false;
}

int main(){
	//freopen("E:\\程序\\C++\\尝试\\aaa.txt","r",stdin);
	int n;
	cin>>n;
	for (int i=1;i<=n;++i){
		depth=0;
		memset(visited,false,sizeof(visited));
		cin >>W>>H;
		//要是能连得通,无论从哪一个点开始都是一样的;
		cout << "Scenario #"<<i<<":"<<endl;
		if (!Dfs(0,0))cout <<"impossible";
		else {
			for(int j=0;j<depth;++j)cout << path[j]; 
		}
		cout << "\n\n";
	} 
}

//欢迎大家一起学习,一起讨论




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章