版权声明:沃斯里德小浩浩啊 https://blog.csdn.net/Healer66/article/details/83754925
链接:
https://cn.vjudge.net/problem/UVA-1589
题意:
黑方只有一个帅,给出黑方帅的坐标,红方可能有车/炮和马,问当前黑方是否被将死。
思路:
见代码
代码目前是错的,但思路正确,有时间再改
#include <bits/stdc++.h>
using namespace std;
typedef struct L
{
int a,b;
};
L General;
L Chariot[2];
L Horse[2];
L Cannon[2];
int i1,i2,i3;
int Qipan[11][10];
int n,x,y;
int tempx,tempy;
char type[10];
int flag;
int checkGenerals(int x,int y)//判断两个将是否直面
{
if(General.b == y)//首先纵坐标必须一样
{
int Flag = 0;
for(int i = x + 1; i < General.a; i++)
{
if(Qipan[i][y])//如果连线上有棋子,那么就不是直面
return 0;
}
return 1;
}
return 0;
}
int checkChariot(int x1,int y1,int x2,int y2)//车
{
//返回0 代表黑帅不会被将死 1 反之
int Flag = 0;
int xj1,yj1,xj2,yj2;
xj1 = x1 < x2? x1 : x2;
xj2 = x1 > x2? x1 : x2;
yj1 = y1 < y2? y1 : y2;
yj2 = y1 > y2? y1 : y2;
//如果一样,说明这次移动,黑帅吃掉了这个车
if(x1 == x2 && y1 == y2)
{
return 0;
}
if(x1 == x2)
{
Flag = 0;
for(int j = yj1 + 1; j < yj2 ; j++)
if(Qipan[x1][j])
Flag = 1;
if(flag == 0) return 1;
}
if(y1 == y2)
{
Flag = 0;
for(int i = xj1 + 1; i < xj2 ; i++)
if(Qipan[i][y1])
Flag = 1;
if(flag == 0)
return 1;
}
return 0;
}
int checkHorse(int x1,int y1,int x2,int y2)//ma
{
//一个马可以八方向移动,但要判断蹩马腿的情况
if(x1+1==x2&&y1+2==y2)
if(Qipan[x1][y1+1]==0)
return 1;
if(x1+1==x2&&y1-2==y2)
if(Qipan[x1][y1-1]==0)
return 1;
if(x1-1==x2&&y1+2==y2)
if(Qipan[x1][y1+1]==0)
return 1;
if(x1-1==x2&&y1-2==y2)
if(Qipan[x1][y1-1]==0)
return 1;
if(x1+2==x2&&y1+1==y2)
if(Qipan[x1+1][y1]==0)
return 1;
if(x1+2==x2&&y1-1==y2)
if(Qipan[x1+1][y1]==0)
return 1;
if(x1-2==x2&&y1+1==y2)
if(Qipan[x1-1][y1]==0)
return 1;
if(x1-2==x2&&y1-1==y2)
if(Qipan[x1-1][y1]==0)
return 1;
return 0;
}
int checkCannon(int x1,int y1,int x2,int y2)//pao
{
int Flag=0;
int xj1,yj1,xj2,yj2;
xj1=x1<x2?x1:x2;
xj2=x1>x2?x1:x2;
yj1=y1<y2?y1:y2;
yj2=y1>y2?y1:y2;
if(x1==x2&&y1==y2) return 0;//判断炮是否直接被吃掉
if(x1==x2)
{
for(int j=yj1+1;j<yj2;j++)
if(Qipan[x1][j]) Flag++;
if(Flag==1) return 1;//中间只有一个棋子
}
if(y1==y2)
{
for(int i=xj1+1;i<xj2;i++)
if(Qipan[i][y1]) Flag++;
if(Flag==1) return 1;//中间只有一个棋子
}
return 0;
}
int checkPoint(int x,int y)//只要黑帅有1种可能被吃,这种移动就不可行,返回0
{
//黑帅被将死checkpoint就返回0
if(checkGenerals(x,y)) return 0;
for(int i = 0; i < i1; i++)
{
if(checkChariot(Chariot[i].a,Chariot[i].b,x,y))
return 0;
}
for(int i = 0; i < i2; i++)
{
if(checkHorse(Horse[i].a,Horse[i].b,x,y))
return 0;
}
for(int i = 0; i < i3; i ++)
{
if(checkCannon(Cannon[i].a,Cannon[i].b,x,y))
return 0;
}
return 1;//没有将死返回1
}
int main()
{
while(cin>>n>>x>>y && n)
{
memset(Qipan,0,sizeof Qipan);//有棋子是1,无棋子是2
Qipan[x][y] = 1;
flag = 0;
i1 = i2 = i3 = 0;
for(int i = 0; i < n; i++)
{
cin>>type>>tempx>>tempy;
Qipan[tempx][tempy] = 1;
if(type[0] = 'G')//帅
{
General.a = tempx;
General.b = tempy;
}
else if(type[0] = 'R')//车
{
Chariot[i1].a = tempx;
Chariot[i1++].b = tempy;
}
else if(type[0] = 'H')//ma
{
Horse[i2].a = tempx;
Horse[i2++].b = tempy;
}
else if(type[0] = 'C')//pao
{
Cannon[i3].a = tempx;
Cannon[i3++].b = tempy;
}
}
//首先判断帅与帅直接相对的情况
if(checkGenerals(x,y))
{
cout<<"NO"<<endl;
continue;
}
flag = 0;
//之后对于黑帅的不同移动进行判断,只要有一种可行,就说明没将死。
if(x + 1 < 4)//可以下移
{
Qipan[x][y] = 0;
Qipan[x+1][y] = 1;
if(checkPoint(x+1,y))
flag = 1;
Qipan[x][y] = 1;
Qipan[x+1][y] = 0;
}
if(flag)
{
cout<<"NO"<<endl;
continue;
}
if(x-1 > 0)
{
Qipan[x][y] = 0;
Qipan[x-1][y] = 1;
if(checkPoint(x-1,y))
flag = 1;
Qipan[x][y] = 1;
Qipan[x-1][y] = 0;
}
if(flag)
{
cout<<"NO"<<endl;
continue;
}
if(y+1 < 7)
{
Qipan[x][y] = 0;
Qipan[x][y+1] = 1;
if(checkPoint(x,y+1))
flag = 1;
Qipan[x][y] = 1;
Qipan[x][y+1] = 0;
}
if(flag)
{
cout<<"NO"<<endl;
continue;
}
if(y-1 > 3)
{
Qipan[x][y] = 0;
Qipan[x][y-1] = 1;
if(checkPoint(x,y-1))
flag = 1;
Qipan[x][y] = 1;
Qipan[x][y-1] = 0;
}
if(flag)
{
cout<<"NO"<<endl;
}
cout<<"YES"<<endl;
}
return 0;
}