[貪心+深搜]馬的迴路

[題目來源 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";
	} 
}

//歡迎大家一起學習,一起討論




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