共42道题,当前是第10

初赛真题

(国王放置)在 $n * m$ 的棋盘上放置 $k$ 个国王要求 $k$ 个国王互相不攻击,有多少种不同的放置方法?
假设国王放置在第 $(x, y)$ 格,国王的攻击区城是
$(x-1,y-1),(x-1,y),(x-1,y+1),(x,y-1),(x,y+1),(x+1,y-1),(x+1,y),(x+1,y+1)$。
读入三个数 $n,m,k$ ,输出答案。

题目利用回溯法求解。棋盘行标号为 $0 \sim n-1$ ,列标号为 $0 \sim m-1$ 。试补全程序。

#include <cstdio>
#include <cstring>

int n, m, k, ans;
int hash[5][5];
void work(int x, int y, int tot) {
    int i, j;
    if (tot == k) {
        ans++;
        return;
    }
    do {
        while (hash[x][y]) {
            y++;
            if (y == m) {
                x++;
                y = ___(1)___;
            }
            if (x == n)
                return;
        }
        for (i = x - 1; i <= x + 1; i++)
            if (i >= && i < n)
                for (j = y - 1; j <= y + 1; j++)
                    if (j >= 0 && j < m)
                        ___(2)___;
        ___(3) ;
        for (i = x - 1; i <= x + 1; i++)
            if (i >= 0 && i < n)
                for (j = y - 1; j <= y + 1; j++)
                    if (j > 0 && j < m)
                        hash[i][i]--;
        ___(4)___;
        if (y == m) {
            x++;
            y = 0;
        }
        if (x == n)
            return;
    } while (1);
}

int main() {
    scanf("%d%d%d", & n, & m, & k);
    ans = 0;
    memset(hash, 0, sizeof(hash));
    ___(5)___;
    printf("%d\n", ans);
    return 0;
}


1. D。
2. D。
3. B。
4. A。
5. D。

这段代码是在通过回溯来求解放置的方案,通过数组 $hash[x][y]$ 来时刻维护目前有哪些格子是可以放置的,每一层递归中枚举放在每一个可以放的位置,然后将附近可以攻击到的位置的 $hash[x][y]$ 进行修改,再向下递归搜索。搜索结束后撤销对 $hash[x][y]$ 数组的修改,再枚举下一个位置。

Question

1. (1) 处应填( )

2. (2) 处应填( )

3. (3) 处应填( )

4. (4) 处应填( )

5. (5) 处应填( )

陈伦制作 版权所无 粤ICP备16127491号-1