设计与算法:A Knight‘s Journey

描述

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.

样例输入

3
1 1
2 3
4 3

样例输出

Scenario #1:
A1

Scenario #2:
impossible

Scenario #3:
A1B3C1A2B4C2A3B1C3A4B2C4

在一个p*q的地方,以马走日的方法,让knight走遍每个点,输出移动的顺序。

走遍每个地方,就从1,1开始吧,看输出也是这样的;

就是在深搜时,进入的点不同,结果就会不同;但都能走遍每个点

//最早是用广搜做了遍,不能找到合适的路径,后用深搜做 
//用广搜的话,就死在那了,深搜还得有个正确的点啊,入深搜的顺序也是关键,它只给了一个标准答案
//其实能走通,答案有很多 
//把每个格做为起点来找,调试多遍不行,后想到,既然每个点都走到,就用一个起点就行了 
//不用每个点都做为起点来查。深搜中用一个cnt计算数,和输入的两数的积相等,就是都走到了 
//Writed by Wangzhimin Date:2023/12/27 -29
//这题用了不少时间呢,用一个结构体是为了输出时值的切换 
//为了先入哪个点d,弄了一天的时间:本身如果能走到每个点,有多种方法,程序只给出了一种
//调试了好多遍呢,就是d[8][2]中的顺序,以68号调整好了,58又不对了等等 
#include<bits/stdc++.h>
using namespace std;
int n,p,q,flag=0;
struct knight{
    int x,y;
}; 
knight shuchu[1005];//输出时保存的值,放的地方 
int d[8][2]={1,-2,-1,-2,-2,-1,2,-1,-2,1,2,1,-1,2,1,2};//八方 ,这费时最长,得查出人家出的顺序 
//先弄上八方,对照答案再调顺序 
int visited[30][30];//标志走过的 
void dfs(int r,int c,int t,int cnt)
{
    if(visited[r][c])
        return;
    if(flag==1)//保证得到一个结果后,不会再找其它的方法 去掉这,就有多种方法了 
    return;
        cnt++;//计数开始吧 
    visited[r][c]=1;
    shuchu[cnt].x=r;//行的值 
    shuchu[cnt].y=c;//列的值 
        if(cnt==p*q)//都走过了 
    {
    printf("Scenario #%d:\n",t);
                 for(int i=1;i<=p*q;i++)
                 printf("%c%d",char(shuchu[i].y+64),shuchu[i].x);
                 printf("\n\n");
                 flag=1;
                 //return;
                 }
     int r1,c1;
       for(int i=0;i<8;i++)//八个方向,如果在范围内就深搜吧 
    {
    r1=d[i][0]+r;
    c1=d[i][1]+c;
    if(r1>=1&&c1>=1&&r1<=p&&c1<=q&&!visited[r1][c1])
        {
            dfs(r1,c1,t,cnt);
            visited[r1][c1]=0;//把返回的再还原,我先前缺了这个,研究了好长时间 
        }
    }
    
 }
int main()
{
    scanf("%d",&n);
    int i;
    for( i=1;i<=n;i++)
    {
        scanf("%d%d",&p,&q);//行,列值,最后先输出列是A等等,行是1-26等 
        flag=0;//找到一个合适的就置1,下面初始化 
             memset(visited,0,sizeof(visited));
             memset(shuchu,0,sizeof(shuchu));
            dfs(1,1,i,0);//从第1个开始,因为都走过,这找一个点开始即可 
       if(flag==0)//没找到能行的 
         {
             printf("Scenario #%d:\n",i);
              cout<<"impossible"<<endl<<endl;}
          }
}

  • 21
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值