【搜索】—深搜遍历 noi openjudge 2.5 A Knight's Journey

来源:互联网 发布:照片营养计算软件 编辑:程序博客网 时间:2024/05/13 14:22

1490:A Knight's Journey


总时间限制: 
1000ms 
内存限制: 
65536kB
描述
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.
样例输入
31 12 34 3
样例输出
Scenario #1:A1Scenario #2:impossibleScenario #3:A1B3C1A2B4C2A3B1C3A4B2C4
来源
TUD Programming Contest 2005, Darmstadt, Germany

分析:
  这是一道类似于马走日的深搜题目,输入棋盘大小,输出马遍历整个棋盘的过程,遍历过程需要字典序最小,马可以从任何地方出发
其实仔细观察一下就会发现(然而我硬是没发现,最后恍然大悟快哭了
因为马要把所有点都走一遍,所以起点在哪个地方都一样,既然如此,那么起点就直接选择字典序最小的A1,接下来搜索的时候,优先往字母小的地点搜索,字母一样就往数字小的地点搜索,这样找到的第一条路径就是字典序最小的路径,而这种操作只需在最开始修改一下dir的值
找到第一条路径后直接打印就可以了

代码如下:
#include<cstdio>#include<cstring>bool s[100][100],f;int dir[10][3]={{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1},{2,1},{-1,2},{1,2}};int a[500],b[500],n,m;void xmy(int i,int j,int k){int x,y;a[k]=i,b[k]=j;if(k==n*m) {f=1;return;}for(int p=0;p<8;p++){x=i+dir[p][0],y=j+dir[p][1];if(x>0&&x<=n&&y>0&&y<=m&&!s[x][y]&&!f){s[x][y]=1;xmy(x,y,k+1);s[x][y]=0;}}}int main(){//freopen("shi.in","r",stdin);int t,o;scanf("%d",&t);for(o=1;o<=t;o++,memset(s,0,sizeof(s))){f=0;s[1][1]=1;printf("Scenario #%d:\n",o);scanf("%d%d",&n,&m);xmy(1,1,1);if(f){for(int i=1;i<=n*m;i++)printf("%c%d",b[i]+64,a[i]);printf("\n");}else printf("impossible\n");if(o!=t) printf("\n");}}

3 1
原创粉丝点击