代码来自https://blog.csdn.net/weixin_41793113/article/details/86721181
在中国象棋中,马是走日字的。一个马的管辖范围指的是当前位置以及一步之内能走到的位置,下图的绿色旗子表示马能走到的位置。
如果一匹马的某个方向被蹩马脚,它就不能往这个方向跳了,如下图所示,海星的位置存在旗子,马就不能往上跳到那两个位置了:
那么问题来了,在一个 n\times mn×m 的棋盘内,如何用最少的马管辖住所有 n\times mn×m 个格子。比如 n=m=3n=m=3 时,最少要用 55 只马才能管辖所有棋盘,一种可能的方案如下:
当 n=m=5n=m=5 时,请你求出用最少马管辖的 方案个数。
#include <cstdio>
#include <cstring>
using namespace std;
int px[4] = {0, 0, 1, -1};
int py[4] = {1, -1, 0, 0};
int dx[4][2] = {-1, 1, -1, 1, 2, 2, -2, -2};
int dy[4][2] = {2, 2, -2, -2, -1, 1, -1, 1};
int vis[5][5], g[5][5];
int n = 5, m = 5;
bool in(int x, int y) { return x >= 0 && x < n && y >= 0 && y < m; }
int main() {
int r = n * m;
int minx = r + r, ans = 0;
for (int s = 0; s < 1 << r; s++) {
memset(vis, 0, sizeof vis);
int cnt = 0;
for (int i = 0; i < r; i++) {
if (s >> i & 1) {
g[i / m][i % m] = 1;
cnt++;
} else {
g[i / m][i % m] = 0;
}
}
if (cnt > minx) continue;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (g[i][j] == 0) continue;
vis[i][j] = 1;
for (int k = 0; k < 4; k++) {
int x = i + px[k], y = j + py[k];
if (in(x, y) && g[x][y] == 0) {
for (int u = 0; u < 2; u++) {
int tx = i + dx[k][u];
int ty = j + dy[k][u];
if (in(tx, ty)) {
vis[tx][ty] = 1;
}
}
}
}
}
}
int ok = 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (vis[i][j] == 0) {
ok = 0;
break;
}
}
}
if (ok) {
if (cnt < minx) {
minx = cnt;
ans = 1;
} else if (cnt == minx) {
ans++;
}
}
}
printf("%d %d\n", minx, ans);
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)