[題目來源 POJ ]
輸入就是棋盤的規格;W和H
翻譯下面的文字,就是要找到一條 馬(象棋玩過吧)的迴路,然後將最小的路徑輸出(字典序),否則就輸出‘impossible’;
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";
}
}
//歡迎大家一起學習,一起討論