UVa 1589 - Xiangqi

题目

给定一个象棋棋盘和若干棋子,判断黑方是否被将死。

分析

模拟。枚举所有黑将的合法移动,判断是否将死。

说明

数据输入貌似有点问题。。。,请用%s

#include <stdio.h>

int board[11][11];

typedef struct _piece
{
	int  r, c;
	char type[5];
}pices;
pices P[10];

int pices_in_segment(int r1, int c1, int r2, int c2)
{
	if (r1 == r2 && c1 == c2)
		return 0;
	int dr = (r1 == r2 ? 0 : (r1 > r2 ? -1 : 1));
	int dc = (c1 == c2 ? 0 : (c1 > c2 ? -1 : 1));
	int size = 0;
	r1 += dr;
	c1 += dc;
	while (r1 != r2 || c1 != c2) {
		if (board[r1][c1])
			++ size;
		r1 += dr;
		c1 += dc;
	}
	return size;
}

int flying_general(int r, int c, pices G)
{
	if (c != G.c) 
		return 0;
	return pices_in_segment(r, c, G.r, G.c) == 0;
}

int check_chariot(int r, int c, pices R)
{
	if (r != R.r && c != R.c) 
		return 0;
	return pices_in_segment(r, c, R.r, R.c) == 0;
}

int check_cannon(int r, int c, pices C)
{
	if (r != C.r && c != C.c) 
		return 0;
	return pices_in_segment(r, c, C.r, C.c) == 1;
}

int horse_move[8][2] = {1, 2, 2, 1, -1, 2, 2, -1, 1, -2, -2, 1, -1, -2, -2, -1};
int horse_hobb[8][2] = {0, 1, 1, 0, 0, 1, 1, 0, 0, -1, -1, 0, 0, -1, -1, 0};
int check_horse(int r, int c, pices H)
{
	int cc, rr;
	for (int i = 0; i < 8; ++ i) {
		rr = H.r + horse_move[i][0];
		cc = H.c + horse_move[i][1];
		if (rr >= 1 && rr <= 10 && cc >= 1 && cc <= 9 && rr == r && cc == c) 
			return board[H.r + horse_hobb[i][0]][H.c + horse_hobb[i][1]] == 0;
	}
	return 0;
} 

int checkmate(int r, int c, int n) 
{
	int flag = 0;
	for (int i = 1; i <= n; ++ i) {
		switch(P[i].type[0]) {
			case 'G': if (flying_general(r, c, P[i])) flag = 1; break;
			case 'R': if (check_chariot(r, c, P[i])) flag = 1; break;
			case 'C': if (check_cannon(r, c, P[i])) flag = 1; break;
			case 'H': if (check_horse(r, c, P[i])) flag = 1; break;
		}
		if (flag) break;
	}
	return flag;
}

int main()
{
	int N, C, R;
	while (~scanf("%d%d%d", &N, &P[0].r, &P[0].c) && N + P[0].r + P[0].c) {
		getchar();
		for (int i = 1; i <= 10; ++ i) 
			for (int j = 1; j <= 9; ++ j) 
				board[i][j] = 0;
		P[0].type[0] = 'G';
		int size = 0, G_id = 0;
		for (int i = 1; i <= N; ++ i) {
			scanf("%s%d%d", &P[i].type, &P[i].r, &P[i].c);
			getchar();
			board[P[i].r][P[i].c] = i;
			if (P[i].type[0] == 'G')
				G_id = i;
		}
		
		if (G_id && flying_general(P[0].r, P[0].c, P[G_id])) {
			puts("NO");
			continue;
		}
		
		int flag = 0, general_move[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
		for (int i = 0; i < 4; ++ i) {
			R = P[0].r + general_move[i][0];
			C = P[0].c + general_move[i][1];
			if (R < 1 || R > 3 || C < 4 || C > 6)
				continue;
			int temp = P[board[R][C]].type[0];
			P[board[R][C]].type[0] = 0;
			if (!checkmate(R, C, N)) {
				flag = 1;
				puts("NO");
				break;
			}
			P[board[R][C]].type[0] = temp;
		}
		if (!flag)
			puts("YES");
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值