版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mobius_strip/article/details/89310544
题目
有一个骑士在一个 R x C 的矩形的地图上行走(如同象棋中的马在棋盘跳动),每次可以走到当前为位置行列相差(±M,±N)或(±N,±M)的格子;有些格子中有水不能跳。如果一个格子可以从偶数个格子跳过来就标记成"偶"的,如果可以从奇数个格子跳过来就标记成"奇"的。问整个地图上为"偶"和"奇"的格子的个数。
分析
图论,搜索。首先用dfs求解所有可以到达的点。然后统计每个点周围可以跳过来的点的个数即可。
说明
注意 M = N 或者其中一个为 0 时,只有四种跳发,其他八种。
#include <stdio.h>
#include <stdlib.h>
int maps[101][101];
int dxy[8][2];
void dfs(int x, int y, int R, int C)
{
if (!maps[x][y]) {
maps[x][y] = 1;
}else {
return;
}
int xx, yy;
for (int k = 0; k < 8; ++ k) {
xx = x + dxy[k][0];
yy = y + dxy[k][1];
if (xx >= 0 && xx < R && yy >= 0 && yy < C && !maps[xx][yy]) {
dfs(xx, yy, R, C);
}
}
}
int main()
{
int T, R, C, M, N, W, x, y, xx, yy;
while (~scanf("%d", &T))
for (int t = 1; t <= T; ++ t) {
scanf("%d%d%d%d%d", &R, &C, &M, &N, &W);
for (int i = 0; i < R; ++ i) {
for (int j = 0; j < C; ++ j) {
maps[i][j] = 0;
}
}
for (int i = 0; i < W; ++ i) {
scanf("%d%d", &x, &y);
maps[x][y] = -1;
}
dxy[0][0] = +M, dxy[0][1] = +N;
dxy[1][0] = +M, dxy[1][1] = -N;
dxy[2][0] = -M, dxy[2][1] = +N;
dxy[3][0] = -M, dxy[3][1] = -N;
dxy[4][0] = +N, dxy[4][1] = +M;
dxy[5][0] = -N, dxy[5][1] = +M;
dxy[6][0] = +N, dxy[6][1] = -M;
dxy[7][0] = -N, dxy[7][1] = -M;
dfs(0, 0, R, C);
int odd = 0, even = 0;
for (int i = 0; i < R; ++ i) {
for (int j = 0; j < C; ++ j) {
if (1 == maps[i][j]) {
int sum = 0;
for (int k = 0; k < 8; ++ k) {
xx = i + dxy[k][0];
yy = j + dxy[k][1];
if (xx >= 0 && xx < R && yy >= 0 && yy < C) {
sum += (1 == maps[xx][yy]);
}
}
if (N == M || 0 == N || 0 == M) {
sum /= 2;
}
if (sum % 2) {
odd ++;
} else if (sum) {
even ++;
}
if (0 == i && 0 == j && 0 == sum) {
even ++;
}
}
}
}
printf("Case %d: %d %d\n", t, even, odd);
}
return 0;
}