[题目来源 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";
}
}
//欢迎大家一起学习,一起讨论