HDU 4121 Xiangqi

本文解析了一道关于中国象棋残局的模拟题,重点在于如何判断红方的将被置于必死之局面。文章通过拆分问题、考虑特定规则(如将的移动范围、蹩马腿等),并提供了详细的AC代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

又是一道大型模拟题。题意为给你一个残局,一边只剩一个将,问任意挪动这个将之后是否都会被将死,完全符合中国象棋的规则。

好了第一步拆分问题。等等,题你真的看清了吗?

有没有想到将只能在中上方9个位置移动?有没有发现象棋棋盘是9*10而不是10*10?有没有考虑照将?有没有考虑蹩马腿。反正我不是没考虑就是考虑错了。

仔细的理解题意,下面的模拟就是简单了,马,车,炮,将,分别作为四个子问题进行考虑,也就是NOIP普及组的模拟题水平了。

下附AC代码。

#include<iostream>
#include<stdio.h>
#include<string.h>
#define maxn 15
using namespace std;
int n,px,py;
char gra[maxn][maxn];
int flag=false;
int fx[maxn]={0,0,0,1,-1};
int fy[maxn]={0,1,-1,0,0};

int mx[maxn]={0,1,1,2,2,-1,-1,-2,-2};
int my[maxn]={0,2,-2,1,-1,2,-2,1,-1};
int bx[maxn]={0,1,1,1,1,-1,-1,-1,-1};
int by[maxn]={0,1,-1,1,-1,1,-1,1,-1};

bool checkche(int nx,int ny)
{
	for(int i=nx+1;i<=10;i++)
	{
		if(gra[i][ny]!=0)
		{
			if(gra[i][ny]=='G' || gra[i][ny]=='R')
			return true;
			else
			break;
		}
	}
	
	for(int i=nx-1;i>=1;i--)
	{
		if(gra[i][ny]!=0)
		{
			if(gra[i][ny]=='R')
			return true;
			else 
			break;
		}
	}
	
	for(int i=ny-1;i>=1;i--)
	{
		if(gra[nx][i]!=0)
		{
			if(gra[nx][i]=='R')
			return true;
			else
			break;
		}
	}
	
	
	for(int i=ny+1;i<=9;i++)
	{
		if(gra[nx][i]!=0)
		{
			if(gra[nx][i]=='R')
			return true;
			else
			break;
		}
	}
	return false;
}
bool checkpao(int nx,int ny)
{
	int blo=0;
	for(int i=ny+1;i<=9;i++)
	{
		if(blo==1 && gra[nx][i]=='C')
		return true;
		if(blo>=2)
		break;
		if(gra[nx][i]!=0)
		blo++;
	}
	
	blo=0;
	for(int i=ny-1;i>=1;i--)
	{
		if(blo==1 && gra[nx][i]=='C')
		return true;
		if(blo>=2)
		break;
		if(gra[nx][i]!=0)
		blo++;
	}
	
	blo=0;
	for(int i=nx+1;i<=10;i++)
	{
		if(blo==1 && gra[i][ny]=='C')
		return true;
		if(blo>=2) break;
		if(gra[i][ny]!=0)
		blo++;
	}
	
	blo=0;
	for(int i=nx-1;i>=1;i--)
	{
		if(blo==1 && gra[i][ny]=='C')
		return true;
		if(blo>=2) break;
		if(gra[i][ny]!=0)
		blo++;
	}
	
	for(int i=1;i<=8;i++)
	{
		int xx=nx+mx[i];
		int yy=ny+my[i];
		int bxx=nx+bx[i];
		int byy=ny+by[i];
		if(1<=xx && xx<=10 && 1<=yy && yy<=9 && gra[xx][yy]=='H' && gra[bxx][byy]==0)
		return true;
	}
	return false;
}
bool dfs(int nx,int ny)
{
	if(checkche(nx,ny))
	return true;
	if(checkpao(nx,ny))
	return true;	
	return false;
}
int main()
{
	while(cin>>n>>px>>py && (n || px || py))
	{
		memset(gra,0,sizeof(gra));
		
		for(int i=1;i<=n;i++)
		{
			char a;
			int x,y;
			cin>>a>>x>>y;
			gra[x][y]=a;
		}
		
		flag=false;
		
		for(int i=1;i<=4;i++)
		{
			int nx=px+fx[i];
			int ny=py+fy[i];
			if(1<=nx && nx<=3 && 4<=ny && ny<=6)
			{
				if(dfs(nx,ny)==false)
				{
					cout<<"NO";
					flag=true;
					break;
				}
			}
		}
		
		if(flag==false)
		cout<<"YES";
		cout<<endl;
	}
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值