2018 ACM ICPC – Notheast Preliminary Regional Qualifier I. Knight's Tour

8 篇文章 0 订阅

Knight’s Tour

Problem Description

In the board game chess, the knight can move in a L shape, moving 2 squares in one direction and 1 square in a perpendicular direction. Here are the 8 possible moves for a knight:

It is well known that a knight can visit every square on a normal 8x8 chessboard without ever visiting the same square twice, which is known as a knight’s tour.
在这里插入图片描述
In this problem, you will find the maximum number of squares that a knight can visit on non- standard chess boards. Each board will have some number of squares in a rectangle. Some squares will be open, but others will may have obstacles, not allowing the night to land on them. The knight can jump over obstacles, just like it can jump over other pieces in chess.

Input
The input will be a series of chess boards. Each board indicates the locations of open squares (O), squares with obstacles (#) and the initial position of the knight (K). Each board will be a rectangle, with at most 15 rows or columns of squares. The input will end with the end of the file.

Output
For each chess board configuration, you should print the maximum number of squares that the knight can visit, starting in its initial position, without visiting a square more than once. You should include the initial square as one of the squares that the knight visits. Note: none of the answers will be greater than 20.

Sample Input

OOO
KOO
OOO
O#OOO
K#O##
#OOOO
OO##OO#
OOO##OO
O#OOO#O
OOOK##O
###O###
###O###
###O###
OOOKOOO
###O###
###O###
###O###
OO##OOOO
OO##OOOO
OO##OOOO
OK###OOO
OOO##OOO
OO###OOO

Sample Output

8
10
16
1
5

Solution

 暴力搜索即可
难点在字符串的输入

AC Code

#include <bits/stdc++.h>

#define _for(i, j, k) for(int i=j;i<=k;++i)
#define END_OF_FILE 2
#define END_OF_LINE 1
#define EMPTY_LINE 3
using namespace std;
char s[25][25];
int n, m;
int dx[8] = {-2, -2, -1, -1, 1, 1, 2, 2};
int dy[8] = {-1, 1, -2, 2, -2, 2, -1, 1};
int vis[25][25];

int dfs(int a, int b) {
    int ret = 0;
    _for(i, 0, 7) {
        int x = a + dx[i], y = b + dy[i];
        if (x >= 0 && y >= 0 && x < n && y < m && s[x][y] == 'O' && !vis[x][y]) {
            vis[x][y] = 1;
            ret = max(ret, dfs(x, y));
            vis[x][y] = 0;
        }
    }
    return ret + 1;
}

int readStr(char *p) {
    (*p++) = getchar();
    if (*(p - 1) == EOF)
        return END_OF_FILE;
    if (*(p - 1) == '\n')
        return EMPTY_LINE;
    while (true) {
        (*p++) = getchar();
        if (*(p - 1) == '\n') {
            *p = 0;
            return END_OF_LINE;
        } else if (*(p - 1) == EOF) {
            *p = 0;
            return END_OF_FILE;
        }
    }
}

int main() {
    while (true) {
        n = 0;
        int flg;
        while (true) {
            flg = readStr(s[n]);
            if (flg == EMPTY_LINE || flg == END_OF_FILE)
                break;
            ++n;
        }
        m = strlen(s[0]);
        if (!m) break;
        _for(i, 0, n - 1) {
            _for(j, 0, m - 1) {
                if (s[i][j] == 'K') {
                    vis[i][j] = 1;
                    cout << dfs(i, j) << endl;
                    vis[i][j] = 0;
                    break;
                }
            }
        }
        if (flg == END_OF_FILE)
            break;
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值