输入] 输入数据≤40组,对于每组数据,第一行有三个数:第一个数代表红方棋数 N(2≤N≤7),第二三个数代表黑将的坐标 接下来N行每行一个字符两个数,代表每个红子的详细信息,字符为棋子种类车(®,马(H),炮©),数字为坐标. 输入所有棋子的位置,保证局面合法并且红方已经将军。
[输出] 对于每组输出数据,如已经将死 ,输出‘YES’,反之输出‘No’
模拟类问题的问题解决思路很重要,根据题意要求的模拟步骤一步步地做,通过循环结构实现每一步,不需要一次性将全部情况表现出来,这样会导致代码的杂乱。
重点问题
- 蹩马腿的判断可以用数组实现,详见代码。
- 棋子车和炮是否将军的判断可以根据棋子与将之间棋子的个数来判断,车与将之间为0,或炮与将之间为1都是将军(核心思想为两棋子间棋子个数的判断车为0,炮为1)。
细节代码:
int cnt(Chess p1, Chess p2)//数棋子的个数
{
int cnt = 0;
if (p1.x == p2.x)
{
int add = (p1.y < p2.y ? 1 : -1);
for (int j = p1.y+add; j != p2.y; j += add)
{
if (tab[p1.x][j] != '0') cnt ++;
}
}
else if (p1.y == p2.y)
{
int add = (p1.x < p2.x ? 1 : -1);
for (int j = p1.x+add; j != p2.x; j += add)
{
if (tab[j][p1.y] != '0') cnt ++;
}
}
else
cnt = 10;
return cnt;
}
//下面的代码用于四类棋子的将军判断
if (pos[i].t == 'G' || pos[i].t == 'R')
{
if (cnt(pos[0], pos[i]) == 0) return false;
}
else if (pos[i].t == 'C')
{
if (cnt(pos[0], pos[i]) == 1) return false;
}
else
{
for (int j = 0; j < 8; j ++)
{
if (pos[i].x + movH[j][0] == pos[0].x
&& pos[i].y + movH[j][1] == pos[0].y
&& tab[pos[i].x + mov[j/2][0]][pos[i].y + mov[j/2][1]] == '0')
return false;
}
}
完整代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<bits/stdc++.h>
using namespace std;
char b[11][10];
struct chess
{
int x,y;
char type;
};
chess ch[20];
int mov[4][2]={0,-1,-1,0,0,1,1,0};
int hmov[8][2]={-1,-2,1,-2,-2,-1,-2,1,-1,2,1,2,2,-1,2,1};
bool legal_g(int x,int y)
{
if(x<1||x>3||y<4||y>6)
return false;
return true;
}
bool legal(int x,int y)
{
if(x<1||x>10||y<1||y>9)
return false;
return true;
}
int cnt(chess c1,chess c2)
{
int cnt = 0;
if(c1.x==c2.x)//在同一行
{
int dif = c1.y>c2.y?-1:1;
for(int i=c1.y+dif;i!=c2.y;i+=dif)
{
if(b[c1.x][i]!='0')
cnt++;
}
}
else if(c1.y==c2.y)
{
int dif = c1.x>c2.x?-1:1;
for(int i=c1.x+dif;i!=c2.x;i+=dif)
{
if(b[i][c1.y]!='0')
cnt++;
}
}
else
cnt=10;
return cnt;
}
int main()
{
/*#ifdef ONLINE_JUDGE
#else
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif*/
int n,x0,y0;
while(cin>>n>>x0>>y0&&n)
{
memset(b,'0',sizeof(b));
ch[0].x=x0,ch[0].y=y0,ch[0].type='g';
for(int i=1;i<=n;i++)
{
cin>>ch[i].type>>ch[i].x>>ch[i].y;
b[ch[i].x][ch[i].y]=ch[i].type;
}
bool ans = false;//判断是否能够存活
for(int k=0;k<4;k++)
{
int nx = x0+mov[k][0];ch[0].x=nx;
int ny = y0+mov[k][1];ch[0].y=ny;
if(legal_g(nx,ny))
{
bool success = true;
char tmp = b[nx][ny];
b[nx][ny]='g';b[x0][y0]='0';
for(int x=1;x<=n;x++)
{
chess c = ch[x];
if(c.type=='G'||c.type=='R')
{
if(!(c.x==nx&&c.y==ny))
{
int cc = cnt(ch[0],c);
if(cc==0){success=false;}
}
}
if(c.type=='C')
{
if(!(c.x==nx&&c.y==ny))
{
int cc = cnt(ch[0],c);
if(cc==1)success=false;
}
}
if(c.type=='H'){
if(!(c.x==nx&&c.y==ny)){
for(int i=0;i<4;i++){
int hx=c.x+mov[i][0],hy=c.y+mov[i][1];
if(legal(hx,hy)&&b[hx][hy]=='0'){
for(int j=i*2;j<=i*2+1;j++){
hx=c.x+hmov[j][0];
hy=c.y+hmov[j][1];
if(legal(hx,hy)&&hx==nx&&hy==ny){
i=4;
success=false;
break;
}
}
}
}
}
}
}
b[x0][y0]='g';b[nx][ny]=tmp;//恢复棋子
if(success)
{
//cout<<nx<<" "<<ny<<endl;
ans=true;
}
}
}
if(ans)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
return 0;
}