●UVa 1589 Xiangqi(模拟)

●赘述题意

给出一个中国象棋残局,告诉各个棋子的位置,黑方只有1枚“将”,红方有至少2枚,至多7枚棋子,包含1枚“帅G”,和若干枚“车R”,“马H”,“炮C”。当前为黑方的回合,问黑方的“将”能否在移动一步后不被“将军”。

●题解

本题就是一个模拟:枚举“将”向四个方向走,是否满足题意。

但比较考察逻辑和代码能力。

但有一个坑点:

“将”在移动时,不能移动到与“帅”照面。

但,恶心的数据会有输入的局面就出现将帅照面的情况,按理说,应是黑方赢了(因为轮到黑方的回合),也就是说在程序中加一个特判。但不需要这么做,或者说:不需要我们这样处理,黑“将”不能在这种情况下直接向“帅”“开大炮”…

●代码(没用网上的二维数组的方法,是直接枚举红棋判断)

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int mv[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
const int hv[8][2]={{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1}};
const int hp[8][2]={{-1,0},{0,1},{0,1},{1,0},{1,0},{0,-1},{0,-1},{-1,0}};
struct node{
	char ch;
	int x,y;
}a[10];
int n;
int abs(int x)
{
	return x>0?x:-x;
}
bool eat(int bx,int by,int p)
{
	return bx==a[p].x&&by==a[p].y;
}
bool CRkill(int bx,int by,int p,int t)
{
	if(a[p].x!=bx&&a[p].y!=by) return 0;
	int fg=a[p].y==by,l,r,cnt=0;
	if(!fg) l=min(a[p].y,by),r=max(a[p].y,by);
	else l=min(a[p].x,bx),r=max(a[p].x,bx);
	for(int i=1;i<=n;i++) if(i!=p&&!eat(bx,by,i))
	{
		if(!fg&&a[i].x==bx&&l<a[i].y&&a[i].y<r) cnt++;
		if(fg&&a[i].y==by&&l<a[i].x&&a[i].x<r) cnt++;
	}
	return cnt==t;
}
bool Hkill(int bx,int by,int p)
{
	if(abs(bx-a[p].x)*abs(by-a[p].y)!=2) return 0;
	int fx,fy;
	for(int i=0;i<8;i++)
	{
		fx=a[p].x+hv[i][0];
		fy=a[p].y+hv[i][1];
		if(fx==bx&&fy==by)
		{
			bool fg=1;
			for(int j=1;j<=n;j++) if(j!=p&&!eat(bx,by,j))
				if(a[j].x==a[p].x+hp[i][0]&&a[j].y==a[p].y+hp[i][1]) fg=0;
			if(fg) return 1;
		}
	}
	return 0;
}
bool live(int bx,int by)
{
	for(int i=1;i<=n;i++) if(!eat(bx,by,i))
	{
		if(a[i].ch=='G'&&CRkill(bx,by,i,0)) return 0;
		if(a[i].ch=='R'&&CRkill(bx,by,i,0)) return 0;
		if(a[i].ch=='C'&&CRkill(bx,by,i,1)) return 0; 
		if(a[i].ch=='H'&&Hkill(bx,by,i)) return 0;
	}
	return 1;
}
bool check(int bx,int by)
{
	int fx,fy;
	for(int i=0;i<4;i++)
	{
		fx=bx+mv[i][0];
		fy=by+mv[i][1];
		if(fx<1||fx>3||fy<4||fy>6) continue;
		if(live(fx,fy)) return 0;		
	}
	return 1;
}
int main()
{
	int bx,by;
	while(1)
	{
		cin>>n>>bx>>by;
		if(!n&&!bx&&!by) break;
		for(int i=1;i<=n;i++) 
			cin>>a[i].ch>>a[i].x>>a[i].y;
		if(check(bx,by)) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
	return 0;
}
原文地址:https://www.cnblogs.com/zj75211/p/7463383.html