POJ 2488 - A Knight's Journey (DFS)

16 篇文章 0 订阅

A Knight's Journey

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 29140 Accepted: 9995

Description

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.

Input

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, . . .

Output

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.

Sample Input

3
1 1
2 3
4 3

Sample Output

Scenario #1:
A1

Scenario #2:
impossible

Scenario #3:
A1B3C1A2B4C2A3B1C3A4B2C4

Source

TUD Programming Contest 2005, Darmstadt, Germany

题意:给一个棋盘,输出马经过所有点刚好一次的路径(最小字典序)或者无解impossible


思路:

DFS


刚开始上来就WA 因为没有看到字典序最小,要字典序,那么每次都是优先选择字典序最小的一步走


#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <queue>
#include <set>

using namespace std;

//#define WIN
#ifdef WIN
typedef __int64 LL;
#define iform "%I64d"
#define oform "%I64d\n"
#define oform1 "%I64d"
#else
typedef long long LL;
#define iform "%lld"
#define oform "%lld\n"
#define oform1 "%lld"
#endif

#define S64I(a) scanf(iform, &(a))
#define P64I(a) printf(oform, (a))
#define S64I1(a) scanf(iform1, &(a))
#define P64I1(a) printf(oform1, (a))
#define FOR(i, s, t) for(int (i)=(s); (i)<(t); (i)++)

const int INF = 0x3f3f3f3f;
const double eps = 10e-9;
const double PI = (4.0*atan(1.0));

const int maxn = 30 + 10;
const int moveX[8] = {-2, -2, -1, -1, 1, 1, 2, 2}; // 排序
const int moveY[8] = {-1, 1, -2, 2, -2, 2, -1, 1};

int n, m;
int vis[maxn][maxn];
int path[maxn][2];

bool dfs(int sx, int sy, int step) {
    path[step][0] = sx;
    path[step][1] = sy;
    if(step == n*m-1) {
        return true;
    }
    for(int i=0; i<8; i++) {
        int nx = sx + moveX[i];
        int ny = sy + moveY[i];
        if(nx <= 0 || nx > n || ny <= 0 || ny > m || vis[nx][ny]) continue;
        vis[nx][ny] = 1;
        int res = dfs(nx, ny, step+1);
        vis[nx][ny] = 0;
        if(res) return true;
    }
    return false;
}

int main() {
    int T;

    scanf("%d", &T);
    for(int kase=1; kase<=T; kase++) {
        scanf("%d%d", &m, &n);
        int ok = 0;
        for(int i=1; i<=n && !ok; i++) {
            for(int j=1; j<=m; j++) {
                memset(vis, 0, sizeof(vis));
                vis[i][j] = 1;
                int res = dfs(i, j, 0);
                vis[i][j] = 0;
                if(res) {
                    ok = 1;
                    break;
                }
            }
        }
        if(kase > 1) putchar('\n');
        printf("Scenario #%d:\n", kase);
        if(ok) {
            for(int i=0; i<n*m; i++) {
                int x = path[i][0];
                int y = path[i][1];
                printf("%c%d", x+'A'-1, y);
            }
            putchar('\n');
        } else {
            puts("impossible");
        }
    }

    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值