UVa 11906 - Knight in a War Grid

版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}

猜你喜欢

转载自blog.csdn.net/mobius_strip/article/details/89310544