题目链接:http://poj.org/problem?id=2488

题意:

  在国际象棋的题盘上有一个骑士,骑士只能走“日”,即站在某一个位置,它可以往周围八个满足条件的格子上跳跃,现在给你一个p * q的矩形格子,让你找一个跳跃顺序(起点自选),使得这个顺序恰好经过矩阵的每一个格子,且每一个格子仅经过一次,即找一个符合跳跃条件的序列,遍历整个矩形格子。如果有多个,那么就输出字典序最小的。

思路:

  貌似可以利用哈密顿通路来解决,但是感觉有点太麻烦,没怎么细想,感觉还是回溯法比较好。首先题目要求字典须,所以拓展节点的顺序不能是随意的,这里把图抽象一下:

A  B C  D  E  F  G

1| *  *  3  *  5  *  *

2| *  1  *  *  *  7  *

3| *  *  *  @ *  *  *

4| *  2  *  *  *  8  *

5| *  *  4  *  6  *  *

假设“@”为骑士某时某刻的位置,可以想到先考虑位置“1”为字典需最小的,紧接着2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8为字典序依次增大的选择,所以每次的选择必须按照上面路径才可保证第一个找到的为字典需最大的。由于这道题的特殊性,可以直接以“A1”为起点,搜索路径,而不用枚举起点进行搜索,大概是因为题目给的所有数据都有以“A1”为起点的路径吧。

代码:

 #include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#include <string>
#define memst(a, b) memset((a), (b), sizeof((a))) typedef long long LL;
using namespace std;
const int MAXN = ;
int map[MAXN + ][MAXN + ];
int stepX[] = {-, , -, , -, , -, };//字典序依次增大的选择
int stepY[] = {-, -, -, -, , , , };
int ok;
int p, q; typedef struct Chess{
char ch;//字母
int nu;//数字
}chess;
chess ve[MAXN + ]; int check(int x, int y) {//剪掉不可能的搜索子树
if(x <= || y <= || x > p || y > q) return ;
if(map[x][y]) return -;
return ;
} void backtrack(int x, int y, int n) {
if(ok) return ;
if(n == p * q) {//找到了一条路经
chess tp;
tp.ch = y + 'A' - , tp.nu = x;
ve[n] = tp;
ok = ;
return ;
}
else {
for(int i = ; i < ; i++) {//往周围八个方向进行试探
int nex = x + stepX[i], ney = y + stepY[i];
chess tp;
tp.ch = y + 'A' - , tp.nu = x;
ve[n] = tp;
if(check(nex, ney) > ) {//剪枝
map[nex][ney] = ;
backtrack(nex, ney, n + );
map[nex][ney] = ; //恢复现场
}
}
}
} int main() {
int T;
scanf("%d", &T);
int kas = ;
while(T--) {
scanf("%d%d", &p, &q);
memset(map, , sizeof(map));
ok = ;
int stX = , stY = ;//起点
map[stX][stY] = ;
memset(&ve, , sizeof(chess));
backtrack(stX, stY, );
printf("Scenario #%d:\n", kas++);
if(ok) {
for(int i = ; i <= p * q; i++) {
printf("%c%d", ve[i].ch, ve[i].nu);
}
printf("\n");
}
else printf("impossible\n");
if (T)printf("\n");
}
return ;
}

  

POJ 2488 A Knight's Journey (回溯法 | DFS)的更多相关文章

  1. POJ 2488 -- A Knight's Journey(骑士游历)

    POJ 2488 -- A Knight's Journey(骑士游历) 题意: 给出一个国际棋盘的大小,判断马能否不重复的走过所有格,并记录下其中按字典序排列的第一种路径. 经典的“骑士游历”问题 ...

  2. POJ 2488 A Knight's Journey(深搜+回溯)

    A Knight's Journey Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other) ...

  3. Poj 2488 A Knight's Journey(搜索)

    Background The knight is getting bored of seeing the same black and white squares again and again an ...

  4. POJ 2488 A Knight's Journey(DFS)

    A Knight's Journey Time Limit: 1000MSMemory Limit: 65536K Total Submissions: 34633Accepted: 11815 De ...

  5. poj 2488 A Knight's Journey 【骑士周游 dfs + 记忆路径】

    题目地址:http://poj.org/problem?id=2488 Sample Input 3 1 1 2 3 4 3 Sample Output Scenario #1: A1 Scenari ...

  6. poj 2488 A Knight's Journey( dfs )

    题目:http://poj.org/problem?id=2488 题意: 给出一个国际棋盘的大小,判断马能否不重复的走过所有格,并记录下其中按字典序排列的第一种路径. #include <io ...

  7. [poj]2488 A Knight's Journey dfs+路径打印

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 45941   Accepted: 15637 Description Bac ...

  8. POJ 2488 A Knight's Journey【DFS】

    补个很久之前的题解.... 题目链接: http://poj.org/problem?id=2488 题意: 马走"日"字,让你为他设计一条道路,走遍所有格,并输出字典序最小的一条 ...

  9. POJ 2488 A Knight's Journey (DFS)

    poj-2488 题意:一个人要走遍一个不大于8*8的国际棋盘,他只能走日字,要输出一条字典序最小的路径 题解: (1)题目上说的"The knight can start and end ...

随机推荐

  1. [洛谷P3203][HNOI2010]弹飞绵羊

    题目大意:有$n$个节点,第$i$个节点有一个弹力系数$k_i$,当到达第$i$个点时,会弹到第$i+k_i$个节点,若没有这个节点($i+k_i>n$)就会被弹飞.有两个操作: $x:$询问从 ...

  2. [NOI2017 D1T1]整数

    题目大意:有一个整数 $x$ ,一开始为 $0$ .有 $n$ 个操作,有两种类型: $1 \;a\; b$:将 $x$ 加上整数 $a\cdot 2^b$ ,其中 $a$ 为一个整数, $b$ 为一 ...

  3. 洛谷 P2486 [SDOI2011]染色/bzoj 2243: [SDOI2011]染色 解题报告

    [SDOI2011]染色 题目描述 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同 ...

  4. 给DOM元素绑定click事件也有学问

    最简单的莫过于使用click方法: 1 <input id="btn" type="button" value="BUTTON" on ...

  5. 怎么给word加底纹

  6. MFC 对话框透明效果

    网上找的资料自己改了改,在这里记录和分享一下,主要是TransparentWnd函数. 在子类的OnShowWindow函数中调用 ShowWindowAlpha() #pragma once tem ...

  7. 【UOJ131/NOI2015D2T2-品酒大会】sam求后缀树

    题目链接:http://uoj.ac/problem/131 题意:给出一个字符串,第i个字符对应的值为a[i], 对于i∈[0,n),求最长公共前缀大于等于i的字串对个数,并求这些字符串对开头对应值 ...

  8. HDU5772 String problem

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission ...

  9. [POJ1082&POJ2348&POJ1067&POJ2505&POJ1960]简单博弈题总结

    鉴于时间紧张...虽然知道博弈是个大课题但是花一个上午时间已经极限了... 希望省选过后再回过头来好好总结一遍吧. 接下来为了看着顺眼一点...还是按照难度顺序吧   POJ1082 一道最简单的博弈 ...

  10. MyBatis系列四 之 智能标签进行查询语句的拼接

    MyBatis系列四 之 智能标签进行查询语句的拼接 使用Foreach进行多条件查询 1.1 foreach使用数组进行多条件查询 在MyBatis的映射文件中进行如下配置 <!--根据数组进 ...