搜索 B - 跳马问题(dfs)

Description

《搜索 B - 跳马问题(dfs)》
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.

Input

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, . . .

Output

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.

Sample Input

3
1 1
2 3
4 3

Sample Output

Scenario #1:A1Scenario #2:impossibleScenario #3:A1B3C1A2B4C2A3B1C3A4B2C4

题意:这个马的遍历方式是 f[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}} 八个方向,如果全能遍历,那么找出按字典序排列最小的序列。

如果要保证按字典序排列最小那就从头开始 深搜 。

#if 0
#include<iostream>
#include<cstring>
using namespace std;
#define max 30
int ax[max],ay[max],q,p;
bool vis[max][max],flag;
int f[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};//方向

int judge(int x,int y)                                             //判断有没有越界
{
 if(x>=0 && x<q && y>=0 && y<p && vis[q][p]==0)
  return 1;
  else
  return 0;
 
}

void dfs(int a,int b,int t)             //a是x b是y t是遍历的个数
{
 	ax[t]=a;
 	ay[t]=b;
 	vis[a][b]=1;
 	
 	if(t==p*q-1)                 //如果全都访问一遍了 那就返回
 	{
 	   flag=1;                      //标记
       return ;
	} 
 for(int i=0; i<8; i++) 
{
	int dx=ax[t]+f[i][0];      //
	int dy=ay[t]+f[i][1];
	
	if(judge(dx,dy) && !vis[dx][dy])
	{
	  vis[dx][dy]=1;    
	  dfs(dx,dy,t+1);
	  if(flag)                   
	  return ;
	  vis[dx][dy]=0; //回溯
	}
}
 return ;
}

int main()
{
int n,ans=1;
cin>>n;

while(n--)
{
 flag=0;
 memset(vis,false,sizeof(vis));          //每一次都要初始化
 memset(ax,0,sizeof(ax));
 memset(ay,0,sizeof(ay));

    cin>>p>>q;
 	cout<<"Scenario #"<<ans<<":"<<endl;
    ans++;
 
  for(int i=0; i<q; i++)
  { 
  	 for(int j=0; j<p; j++)
  {
  	dfs(i,j,0);
  	if(flag) 
  	break;	
  }
  if(flag)
  break;
  }
  
  if(flag)
  {  
  for(int i=0; i<q*p; i++) 
  cout<<char(ax[i]+'A')<<ay[i]+1; 
  cout<<endl<<endl;
  }
  else 
  cout<<"impossible"<<endl<<endl;
 
 	
}	
 	
} 
#endif 

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