POJ2488 骑士的旅程

简介: POJ2488 骑士的旅程

POJ2488 骑士的旅程


题目描述


骑士一次又一次地看到相同的黑白方块而感到厌倦,并决定环游世界。每当骑士移动时,它是一个方向上的两个正方形和一个垂直于此的正方形。骑士的世界是他生活的棋盘。我们的骑士生活在棋盘上,棋盘面积比普通的8 * 8棋盘小,但它仍然是长方形的。你能帮助这个冒险骑士做出旅行计划吗



输入


找到一条路径,使骑士可以拜访每个广场一次。骑士可以在棋盘的任何正方形上开始和结束。


输出

输入在第一行中以正整数n开头。以下各行包含n个测试用例。每个测试用例由一行包含两个正整数p和q的行组成,因此1 <= p * q <=26。这表示 p * q棋盘,其中p描述了多少个不同的正方形数1,2,3…,q描述存在多少个不同的正方形字母,这些是拉丁字母的前q个字母:A ,B,C…


输入样例

3

1 1

2 3

4 3


输出样例

Scenario #1:

A1

Scenario #2:

impossible

Scenario #3:

A1B3C1A2B4C2A3B1C3A4B2C4


思路分析

本题主要考察DFS.但要明白这个题的意思是能否只走一遍(不回头)将这个地图走完,这与普通的DFS不同,普通的DFS是一直走,走不通后返回某处继续进行搜索.所以这个题还要用到回溯思想,如果不重复走一遍走完了就做一个标记,算法就结束.否则在某种DFS下走到某一步时按照马跳的规则无路可走但地图还没有走完时,就撤销这一步,切换其他路线.撤销这一步后应该重置该点,以便走其他路线时该点是未访问过的,而不是像普通的DFS当做已经访问过了.

如果有多种方式可以不重复走一遍的走完,需要输出按字典序最小的路径,而注意到国际象棋的棋盘是列为字母,行为数字,如果能够不回头走一遍的走完,一定会经过A1点,所以我们应该从A1开始搜索,以确保之后得到的路径字典序是最小的(也就是说如果路径不以A1开始,该路径一定不是字典序最小路径),而且我们应该确保优先选择的方向是字典序最小的方向,这样我们最先得到的路径就是字典序最小的。


算法设计

20210227234530212.jpg

2.图是p行q列的,行用数字标识,列用大写字母标识,但是输出时,

先输出了大写字母,然后是数字,因此写程序时,把图翻转一下,看作q行p列的,这样就可以先行后列输出了(所以上图坐标也进行了反转)。

3. 从1,1开始,从八个方向深度优先搜索,判断是否可行,如果可行,记录搜索步,从当前结点出发继续深搜;

4. 当步数达到n*m说明找到一条路径。。

5.输出该路径。


参考代码

#include<iostream>
#include<string.h>
using namespace std;
int map[30][30],m,n;//m:行, n:列  map:标记是否走过.
bool flag;//控制是否完成旅行.
int path[30][2];//记录路径
int dir[8][2] = { -2,-1,-2,1,-1,-2,-1,2,1,-2,1,2,2,-1,2,1 };//-2,-1,-1,-2,1,-2,2,-1,2,1,1,2,-1,2,-2,1
bool dfs(int x, int y, int step)
{
  if (step == m * n)
    return flag = true;
  for (int i = 0; i < 8; i++)
  {
    int x2 = x + dir[i][0];
    int y2 = y + dir[i][1];
    if (x2 >= 1 && x2 <= m && y2 >= 1 && y2 <= n && !map[x2][y2] && !flag)
    {
      map[x2][y2] = 1;
      path[step][0] = x2;
      path[step][1] = y2;
      dfs(x2, y2, step+1);
      map[x2][y2] = 0;//如果该路不通,则回溯.
    }
  }
  return flag;
}
int main()
{
  int T = 0;
  cin >> T;
  for(int i = 1; i <= T; i++)
  {
    memset(map, 0, sizeof(map));
    flag = false;
    cin >> n >> m;
    int step = 1;
    path[0][0] = 1;
    path[0][1] = 1;
    map[1][1] = 1;
    cout << "Scenario #" << i<<":"<<endl;
    if (dfs(1, 1, 1))//如果有路
    {
      for (int j = 0; j < m * n; j++)
      {
        cout << (char)(path[j][0]+'A' - 1) << path[j][1];
      }
      cout << endl;
    }
    else
    {
      cout << "impossible" << endl;
    }
    cout << endl;
  }
  return 0;
}


相关文章
|
3月前
|
存储 算法 数据可视化
Dijkstra算法在《庆余年》中的应用:范闲的皇宫之旅
Dijkstra算法在《庆余年》中的应用:范闲的皇宫之旅
|
3月前
|
Java
技术经验分享:hdu3549初试最大流问题
技术经验分享:hdu3549初试最大流问题
12 0
|
算法
【过河卒】回溯算法保姆式解题
【过河卒】回溯算法保姆式解题
82 0
|
定位技术
国庆七天乐,要猛! ——经典迷宫问题
国庆七天乐,要猛! ——经典迷宫问题
79 0
|
存储 人工智能 JavaScript
【寒假每日一题】AcWing 4510. 寻宝!大冒险!
目录 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解
130 0
|
人工智能 算法 BI
【寒假每日一题】AcWing 4656. 技能升级(难到飞起)
目录 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 三、知识风暴 1、贪心算法 2、归并算法 3、二分查找法
54 0
|
存储
【蓝桥杯集训·每日一题】AcWing 4309. 消灭老鼠
文章目录 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 三、知识风暴 最大公约数
79 0
|
JavaScript BI
【蓝桥杯集训·周赛】AcWing 第96场周赛
文章目录 第一题 AcWing 4876. 完美数 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 第二题 AcWing 4877. 最大价值 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 第三题 AcWing 4878. 维护数组 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解
81 0
|
存储 机器学习/深度学习 人工智能
【蓝桥杯集训·周赛】AcWing 第94场周赛
文章目录 第一题 AcWing 4870. 装物品 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 第二题 AcWing 4871. 最早时刻 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 第三题 AcWing 4872. 最短路之和 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解
68 0
|
存储 机器学习/深度学习 人工智能
【蓝桥杯集训·周赛】AcWing 第 95 场周赛
文章目录 第一题 AcWing 4873. 简单计算 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 第二题 AcWing 4874. 约数 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 第三题 AcWing 4875. 整数游戏 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解
102 0