You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

AcWing 1116 . 马走日

一、题目描述

马在中国象棋以日字形规则移动。

请编写一段程序,给定 nm 大小的棋盘,以及马的初始位置 (xy),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点。

输入格式 第一行为整数 T,表示测试数据组数。

每一组测试数据包含一行,为四个整数,分别为棋盘的大小以及初始位置坐标 n,m,x,y

输出格式 每组测试数据包含一行,为一个整数,表示马能遍历棋盘的 途径总数 ,若无法遍历棋盘上的所有点则输出 0

数据范围 1≤T≤9,1≤m,n≤9,1≤n×m≤28,0≤x≤n1,0≤y≤m1

输入样例

1
5 4 0 0

输出样例

32

二、题目解析

  • 途径总数,应该是一道dfs
  • 如何算是遍历所有点呢?应该是记录每个位置是否走过,重复的不能再走,每走一个位置记录一下cnt++,如果cnt==n*m,就是得到了一组解。

三、实现代码

#include <bits/stdc++.h>

using namespace std;
const int N = 10;

int n, m;
bool st[N][N]; // 是否走过
int ans;

// 八个方向
int dx[] = {-2, -1, 1, 2, 2, 1, -1, -2};
int dy[] = {1, 2, 2, 1, -1, -2, -2, -1};

// cnt:已经走了多少个格子
void dfs(int x, int y, int cnt) {
    // 收集答案
    if (cnt == n * m) {
        ans++;
        return;
    }

    for (int i = 0; i < 8; i++) {
        int tx = x + dx[i], ty = y + dy[i];
        if (tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
        if (st[tx][ty]) continue;

        // 标识当前格子已使用
        st[tx][ty] = 1;
        dfs(tx, ty, cnt + 1);
        // 标识当前格子未使用
        st[tx][ty] = 0;
    }
}

int main() {
    int T;
    cin >> T;
    while (T--) {
        int x, y;
        cin >> n >> m >> x >> y;

        // 清空状态数组
        memset(st, 0, sizeof st);
        // 清空方案数
        ans = 0;
        // 标识起点已访问
        st[x][y] = 1;
        // 从(x,y)出发目前的访问个数为1
        dfs(x, y, 1);
        // 最终有多少条路径
        cout << ans << endl;
    }
    return 0;
}