poj2488 A Knight’s Journey

poj2488 A Knight’s Journey

http://poj.org/problem?id=2488

 

题目大意:骑士厌倦了一遍又一遍地看到同样的黑白方块,于是决定去旅行。

世界各地。当一个骑士移动时,他走的是“日”字。骑士的世界是他赖以生存的棋盘。我们的骑士生活在一个棋盘上,它的面积比普通的8 * 8板要小,但它仍然是矩形的。你能帮这个冒险的骑士制定旅行计划吗? 找到一条路,这样骑士每一次都能到每一个广场。骑士可以在棋盘的任何方格上开始和结束。输入从第一行的正整数n开始。下面的行包含n个测试用例。每个测试用例由一个带有两个正整数p和q的单行组成,其中1 <= p * q <= 26。这表示一个p * q棋盘,其中p描述了多少个不同的数1,…p存在,q描述存在多少个不同的字母。这些是拉丁字母表中的第一个q字母:A,…每个场景的输出从包含“Scenario #i:”的一行开始,其中i是从1开始的场景的数量。然后打印一行一行,其中包含了字母顺序的第一路径,它访问棋盘上的所有方块,然后是空行。通过将访问的方块的名称连接起来,可以在一行中给出路径。每个方名称由大写字母和数字组成。

如果不存在这样的路径,那么您应该在一行上输出impossible的内容。

 

也就是说横坐标时是字母(向右为正),纵坐标是数字(向下为正),骑士需要走完全图的方格,并找出包含了字母顺序的第一条路径,那么这就暗示了骑士的起点坐标一定是A1,只有是按字母排序第一个一定是A1。骑士走的是“日”字,那么根据字母排序骑士的横坐标和纵坐标减少或增加的遍历顺序是8个方向(-2,-1)(-2,1)(-1,-2)(-1,2)(1,-2)(1,2)(2,-1)(2,1),这样的遍历顺序,得到的第一条路径一定是按字母顺序的路径。

 

算法思想:回溯法,问题的解空间树是一颗八叉树,分别对应八个方向,设置相应的剪枝函数,1)如果出界,舍弃相应子树;2)如果找到了一条路径(一定是按字母排序的路径),用一个isSoluted记录,如果问题解决,则减去相应子树;3)我们可以用visited[ ][ ]记录该方格被访问,减去相应子树(重复走回路),并在回溯时设为未访问。

 1 #include <cstring>//使用memset()
 2 #include <iostream>
 3 using namespace std;
 4 //按字典排序的行走方向       8叉树
 5 const int dx[8] = { -2, -2, -1, -1, 1, 1, 2, 2 };
 6 const int dy[8] = { -1, 1, -2, 2, -2, 2, -1, 1 };
 7 const int N = 27;
 8 bool visited[N][N];//判断方格是否被访问
 9 struct step {
   //走路的记录
10     char x, y;
11 };
12 step path[N];//记录路径的
13 bool isSoluted;//能否走通
14 int cases, p, q;//记录案例数,p行123... q列ABC...
15 void Backtrade(int x, int y, int t)//x 和 y 为当前坐标 t为深度
16 {
17     path[t].x = x + 'A' - 1;   //转为 char 记录走的路径
18     path[t].y = y + '0';
19     if (t == p * q)//如果有一条路走完全部 则可解 直接退出回溯
20     {
21         isSoluted = true;
22         return;
23     }
24     for (int i = 0; i < 8; i++)
25     {
26         int nx = x + dx[i];
27         int ny = y + dy[i];
28         //剪枝函数 出界 或 已访问过 或 问题已解决 不进入相应子树
29         if (0 < nx && nx <= q && 0 < ny && ny <= p&& !visited[nx][ny] && !isSoluted)
30         {
31             visited[nx][ny] = true;
32             Backtrade(nx, ny, t + 1);
33             visited[nx][ny] = false;//回溯时撤回标记
34         }
35     }
36 }
37 int main()
38 {
39     cin>>cases;
40     for (int c = 1; c <= cases; c++)
41     {
42         isSoluted = false;
43         cin >> p >> q;
44         memset(visited, false, sizeof(visited));
45         visited[1][1] = true;    //从第一个字典序起点开始走
46         Backtrade(1, 1, 1);
47         cout<<"Scenario #"<<c<<":"<<endl;
48         if (isSoluted)
49         {
50             for (int i = 1; i <= p * q; i++)
51                 cout << path[i].x << path[i].y;
52             cout << endl;
53         }
54         else
55             cout<<"impossible"<<endl;
56         cout << endl;
57     }
58     return 0;
59 }

 

转载于:https://www.cnblogs.com/DA799422035/p/8994075.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/101680.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • mysql怎么解决1045错误_Navicat for MySQL 1045错误如何解决[通俗易懂]

    mysql怎么解决1045错误_Navicat for MySQL 1045错误如何解决[通俗易懂]在使用Navicat连接MySQL数据库时很多人都会遇到1045错误,主要原因是,你输入的用户名或密码错误被拒绝访问了,如果你不想重装,那么就需要找回密码或者重置密码。NavicatforMySQL1045错误问题描述:1045-Accessdeniedforuser’root’@’localhost'(usingpassword:YES)原因分析:当登录MySQL数据库…

    2022年5月8日
  • sp_executesql_sp_executesql存储过程简介和示例

    sp_executesql_sp_executesql存储过程简介和示例sp_executesqlThesp_executesqlisabuilt-instoredprocedureinSQLServerthatenablestoexecuteofthedynamicallyconstructedSQLstatementsorbatches.Executingthedynamicallyconstructe…

    2022年5月22日
  • CultureInfo名字

    CultureInfo名字 
    ThefollowingpredefinedCultureInfonamesandidentifiersareacceptedandusedbythisclassandotherclassesintheSystem.Globalizationnamespace.
     CultureNameCultureIdentifierLanguage-Country/Region””(emptystring)0x007Finvariantcultu

    2022年6月19日
  • MySQL的字段类型_mysql数据库字段类型

    MySQL的字段类型_mysql数据库字段类型前言:要了解一个数据库,我们必须了解其支持的数据类型。MySQL支持大量的字段类型,其中常用的也有很多。前面文章我们也讲过int及varchar类型的用法,但一直没有全面讲过字段类型,本篇文章我们将把字段类型一网打尽,讲一讲常用字段类型的用法。常用的字段类型大致可以分为数值类型、字符串类型、日期时间类型三大类,下面我们按照分类依次来介绍下。1.数值类型数值类型大类又可以分为整型、浮点型、…

    2022年9月6日
  • DotNetTextBox控件应用实例之简单留言簿

    DotNetTextBox控件应用实例之简单留言簿

    2021年7月9日
  • SPPNet总结

    SPPNet总结背景:RCNN使用CNN作为特征提取器,首次使得目标检测跨入深度学习的阶段。但是在RCNN中,因为全连接层的神经元个数是固定的(权重矩阵的维数是固定的),所以采取对于每一个区域候选都需要首先将图片放缩到固定尺寸(227×227),然后为每个区域候选提取CNN特征的方案。这里存在两个瓶颈,第一重复为每个regionproposal提取特征是及其费时的,SelectiveSearch对于每幅图片产生2k左右个regionproposal,也就是意味着一幅图片需要经过2k次完整的CNN计算得到最终的结果。

    2022年5月2日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号