题目链接: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. GET传值

    发送页: <form id="form1" runat="server"> <div> <asp:TextBox ID=</ ...

  2. hihocoder 后缀自动机专题

    一.后缀自动机基本概念的理解 1.首先后缀自动机的状态是由子串的endpos来决定的 子串的endpos是指一个子串可以在原字符串的哪些位置进行匹配, endpos构成的不同集合划分成不同的状态 关于 ...

  3. 洛谷 P1829 [国家集训队]Crash的数字表格 / JZPTAB 解题报告

    [国家集训队]Crash的数字表格 / JZPTAB 题意 求\(\sum\limits_{i=1}^n\sum\limits_{j=1}^mlcm(i,j)\),\(n,m\le 10^7\) 鉴于 ...

  4. UVA 11995 STL 使用

    There is a bag-like data structure, supporting two operations: 1 x Throw an element x into the bag. ...

  5. [codeforces gym Matrix God]随机矩阵乘法

    题目链接:http://codeforces.com/gym/101341/problem/I 随机真是一个神奇的方法.原本矩阵乘法是n^3的复杂度,但是这个题是让判断两个矩阵是否相等,只需要在两个矩 ...

  6. linux 下查看网卡工作速率

    [root@hadoop058 ~]# mii-tool eth0: negotiated 100baseTx-FD, link ok 100M linux 下查看网卡工作速率 Ethtool是用于查 ...

  7. 慕课网javascript 进阶篇 第九章 编程练习

    把平常撸的码来博客上再撸一遍既可以加深理解,又可以理清思维.还是很纯很纯的小白,各位看官老爷们,不要嫌弃.最近都是晚睡,昨晚也不例外,两点多睡的.故,八点起来的人不是很舒服,脑袋有点晕呼呼,鉴于昨晚看 ...

  8. 动态规划:高维DP

    例子当然是王八棋这道题,这道题以前是写烂了 先来一个大暴力,zlw教的暴力~~ #include<iostream> using namespace std; ,maxm=; ]; int ...

  9. Gradle体验/第一篇:下装、安装、配置、体验

    http://jingyan.baidu.com/article/4d58d541167bc69dd4e9c009.html

  10. 【CF1023F】Mobile Phone Network(dsu,MST)

    题意: 保证原边以边权单调非减的顺序读入 思路:先把未知边加入,再加入原始边做MST,考虑从大到小,用数据结构维护,每一条原始边相当两个链赋值操作,每一条未知边相当于一个询问,答案即为询问之和 LCT ...