版权声明:本人菜鸟一只,如文章有错误或您有高见,请不吝赐教 https://blog.csdn.net/qq_41138935/article/details/83381134
我的代码仅过了题目数据。
思路:穷举黑方【将】的下一步(上下左右),
如果某一步没被将,则说明红方没有将死黑方,输出NO
否则如果黑方【将】所有能被走的方向都被将,输出YES
题目地址:https://vjudge.net/problem/UVA-1589
结果图:
代码:
#include<iostream>
#include<cstring>
using namespace std;
char c[11][10]; //棋盘 从(1,1)开始
bool win=false;
bool f(int xx,int yy){ //被将军返回true
bool flag=true;
int x,y;
//左
x=xx;
y=yy;
for(int i=y+1;i<10;i++){
if(c[x][i]=='R'){ //遇到车
flag=false;
break;
}
else if(c[x][i]=='H'||c[x][i]=='C'||c[x][i]=='C'){
int tag=1;
int j=i+1;
bool tag1=false;
while(j<=10){
if(c[x][j]=='C') //马后炮
tag+=1;
else if(c[x][j]=='R'||c[x][j]=='H'){
tag=3;
}
if(tag==2){
flag=false;
tag1=true;
break;
}
else if(tag==3)
break;
j++;
}
if(tag1)
break;
}
}
//下
x=xx;
y=yy;
for(int i=x+1;i<=10;i++){
if(c[i][y]=='R'){ //遇到车
flag=false;
break;
}else if(c[i][y]=='H'||c[i][y]=='C'||c[i][y]=='C'){
int tag=1;
int j=i+1;
bool tag1=false;
while(j<=10){
if(c[j][y]=='C') //马后炮
tag+=1;
else if(c[j][y]=='R'||c[j][y]=='H'){
tag=3;
}
if(tag==2){
flag=false;
tag1=true;
break;
}
else if(tag==3)
break;
j++;
}
if(tag1)
break;
}
}
//右
x=xx;
y=yy;
for(int i=y-1;y>=1;y--){
if(c[x][i]=='R'){
flag=false;
break;
}
else if(c[x][i]=='H'||c[x][i]=='C'||c[x][i]=='C'){
int tag=1;
int j=i-1;
bool tag1=false;
while(j>=1){
if(c[x][i]=='C') //马后炮
tag+=1;
else if(c[x][i]=='R'||c[x][i]=='H'){
tag=3;
}
if(tag==2){
flag=false;
tag1=true;
break;
}
else if(tag==3)
break;
j--;
}
if(tag1)
break;
}
}
//上
x=xx;
y=yy;
for(int i=x-1;i>=1;i--){
if(c[i][y]=='R'){
flag=false;
break;
}
else if(c[i][y]=='H'||c[i][y]=='C'||c[i][y]=='C'){
int tag=1;
int j=i-1;
bool tag1=false;
while(j>=1){
if(c[i][y]=='C') //马后炮
tag+=1;
else if(c[i][y]=='R'||c[i][y]=='H'){
tag=3;
}
if(tag==2){
flag=false;
tag1=true;
break;
}
else if(tag==3)
break;
j--;
}
if(tag1)
break;
}
}
//马的判断
x=xx;
y=yy;
if(x==1){
if(c[x][y-1]=='0'){
if(c[x+1][y-2]=='H'){
flag=false;
}
}
if(c[x+1][y]=='0'){
if(c[x+2][y-1]=='H'||c[x+2][y+1]=='H'){
flag=false;
}
}
if(c[x][y+1]=='0'){
if(c[x+1][y+2]=='H'){
flag=false;
}
}
}else if(x==2){
if(c[x][y-1]=='0'){
if(c[x+1][y-2]=='H'||c[x-1][y-2]=='H'){
flag=false;
}
}
if(c[x+1][y]=='0'){
if(c[x+2][y-1]=='H'||c[x+2][y+1]=='H'){
flag=false;
}
}
if(c[x][y+1]=='0'){
if(c[x+1][y+2]=='H'||c[x-1][y+2]=='H'){
flag=false;
}
}
}else if(x==3){
if(c[x-1][y]=='0'){
if(c[x-2][y-1]=='H'||c[x-2][y+1]=='H')
flag=false;
}
if(c[x+1][y]=='0'){
if(c[x+2][y-1]=='H'||c[x+2][y+1]=='H'){
flag=false;
}
}
if(c[x][y-1]=='0'){
if(c[x-1][y-2]=='H'||c[x+1][y-2]=='H'){
flag=false;
}
}
if(c[x][y+1]=='0'){
if(c[x+1][y+2]=='H'||c[x-1][y+2]=='H')
flag=false;
}
}
//对将
x=xx;
y=yy;
int t=0;
for(int i=x+1;i<=10;i++){ //飞车
if(c[i][y]!='0'&&c[i][y]!='G')
t=1;
if(c[i][y]=='G'&&t==0){
flag=false;
break;
}
}
if(!flag){ //被将军返回true
return true;
}
return false;
}
int main(){
int x,y; //将的位置
int n,x1,y1;
char g;
int temp_x,temp_y; //黑方将的坐标
while(cin>>n>>x>>y&&n!=0&&x!=0&&y!=0){
memset(c,'0',sizeof(c)); //棋盘初始化
win=false;
bool tagjiangjun=true;
c[x][y]='B'; //黑方 将
for(int i=0;i<n;i++){
cin>>g>>x1>>y1;
c[x1][y1]=g;
}
//打印棋盘
// for(int i=1;i<11;i++){
// for(int j=1;j<10;j++){
// cout<<c[i][j];
// }
// cout<<endl;
// }
temp_x=x;
temp_y=y;
temp_y+=1; //向右移动
if(temp_y>=4&&temp_y<=6){
//判断是否还被将军
if(f(temp_x,temp_y)){
win=true;
}else{
tagjiangjun=false;
}
}
temp_x=x;
temp_y=y;
temp_x+=1; //向下
if(temp_x>=1&&temp_x<=3){
//判断是否还被将军
if(f(temp_x,temp_y)){
win=true;
}else{
tagjiangjun=false;
}
}
temp_x=x;
temp_y=y;
temp_y-=1; //向左
if(temp_y>=4&&temp_y<=6){
//判断是否还被将军
if(f(temp_x,temp_y)){
win=true;
}else{
tagjiangjun=false;
}
}
temp_x=x;
temp_y=y;
temp_x-=1; //向上
if(temp_x>=1&&temp_x<=3){
//判断是否还被将军
if(f(temp_x,temp_y)){
win=true;
}else{
tagjiangjun=false;
}
}
if(win&&tagjiangjun)
cout<<"YES"<<endl;
if(!tagjiangjun)
cout<<"NO"<<endl;
}
return 0;
}
网上看到的代码:
#include <cstdio>
#define RD(X) if(s[X].x||s[X].y)s[X+1].x=x,s[X+1].y=y;else s[X].x=x,s[X].y=y
#define CHECKR(X) (check(s[X],m,n)&&!between(s[X],m,n))
#define CHECKC(X) (check(s[X],m,n)&&between(s[X],m,n)==1)
char c;
int x,y,N;
struct point{int x,y;};
point s[8];//B,G,R1,R2,H1,H2,C1,C2
int mx[4]={1,-1,0,0},my[4]={0,0,1,-1};
int abs(int tt){return ((tt<0)?-tt:tt);}
int mid(int a1,int a2,int a3){return ((a1<a2&&a2<a3)||(a1>a2&&a2>a3));}
int check(point TT,int x2,int y2){return ((TT.x==x2&&TT.y!=y2)||(TT.y==y2&&TT.x!=x2));}
int between(point T,int x2,int y2){
int xx=0;
for(int i=1;i<8;i++)
xx+=(mid(T.x,s[i].x,x2)&&check(s[i],x2,y2))+(mid(T.y,s[i].y,y2)&&check(s[i],x2,y2));
return xx;
}
int checkH(point _T,int mm,int nn){
int dm=_T.x-mm,dn=_T.y-nn,am=abs(dm),an=abs(dn);
return (am+an==3&&am&&an&&!between(_T,_T.x-(int(dm/2)<<1),_T.y-(int(dn/2)<<1)));
}
int Try(int m,int n){
if(m<1||m>3||n<4||n>6||\
(n==s[1].y&&!between(s[1],m,n))||\
CHECKR(2)||CHECKR(3)||\
CHECKC(6)||CHECKC(7))return 0;
return !(checkH(s[4],m,n)||checkH(s[5],m,n));
}
int main(){
while(~scanf("%d%d%d",&N,&s[0].x,&s[0].y)&&(N||s[0].x||s[0].y)){
for(int i=1;i<8;i++)s[i].x=s[i].y=0;
while(N--){
scanf(" %c%d%d",&c,&x,&y);
if(c=='G')s[1].x=x,s[1].y=y;
if(c=='R')RD(2);
if(c=='H')RD(4);
if(c=='C')RD(6);
}
for(int i=0;i<4;i++)
if(Try(s[0].x+mx[i],s[0].y+my[i])){printf("NO\n");goto lable;}
printf("YES\n");lable:;
}
return 0;
}
还有一种方法,把红方棋子能走的全设为1,不能走的设为0,判断黑方【将】上下左右。