题目链接:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1137
题目大意:
给你一副国际象棋的格局,让你判断哪方被将军了。
解题思路:
模拟题,考虑每方每一颗棋子的对另一方的攻击范围,如果对方王在某一颗棋子的攻击范围内,则对方被将军了。
注意只有马能越过棋子,其余棋子不能越过棋子,如果挡住了,则攻击范围在这个方向上终止。
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#define eps 1e-6
#define INF (1<<20)
#define PI acos(-1.0)
using namespace std;
bool judge(int x,int y) //判断坐标是否越界
{
if(x>=1&&x<=8&&y>=1&&y<=8)
return true;
return false;
}
int main()
{
char mmap[100][100];
int black[70][5],white[70][5],numb=0,numw=0;//numb,numw分别代表黑棋和白棋的数量
int bk,wk,ca=0,flag=0; //bk,wk分别代表黑王和白王的位置
do
{
//if(flag==1) //空行的读取
// getline(cin,temp);
numb=numw=flag=0; //注意清零runtime error 了好多次
for(int i=1;i<=8;i++)
{
for(int j=1;j<=8;j++)
{
scanf("%c",&mmap[i][j]);
if(mmap[i][j]!='.')
{
flag=1;
if(mmap[i][j]>='a'&&mmap[i][j]<='z')
{
numb++;
black[numb][1]=i;
black[numb][2]=j;
if(mmap[i][j]=='k')
bk=numb;
}
else
{
numw++;
white[numw][1]=i;
white[numw][2]=j;
if(mmap[i][j]=='K')
wk=numw;
}
}
}
getchar();//读入每一行的回车
}
getchar();//读入每一组的空行
//printf("flag:%d\n",flag);
int winb=0;
for(int i=1;i<=numb;i++)
{
int can1=0,can2=0;
int can3=0,can4=0;
if(i==bk)
continue;
int x=black[i][1],y=black[i][2];
switch(mmap[x][y])
{
//如果是卒的话
case 'p':if((judge(x+1,y-1)&&mmap[x+1][y-1]=='K')||(judge(x+1,y+1)&&mmap[x+1][y+1]=='K'))
{
winb=1;
break;
}
break;
//如果是马的话
case 'n':if((judge(x-1,y+2)&&mmap[x-1][y+2]=='K')||(judge(x+1,y+2)&&mmap[x+1][y+2]=='K'))
{
winb=1;
break;
}
if((judge(x-2,y+1)&&mmap[x-2][y+1]=='K')||(judge(x+2,y+1)&&mmap[x+2][y+1]=='K'))
{
winb=1;
break;
}
if((judge(x-2,y-1)&&mmap[x-2][y-1]=='K')||(judge(x+2,y-1)&&mmap[x+2][y-1]=='K'))
{
winb=1;
break;
}
if((judge(x-1,y-2)&&mmap[x-1][y-2]=='K')||(judge(x+1,y-2)&&mmap[x+1][y-2]=='K'))
{
winb=1;
break;
}
break; //注意要跳出来,不然如果不满足的话,继续执行下一个case
case 'b': //如果是象的话
for(int i=1;i<=8-x;i++)
{
if(judge(x+i,y+i))
{
if(mmap[x+i][y+i]=='K')
{
if(can1==0)
{
winb=1;
break;
}
}
else if(mmap[x+i][y+i]!='.')
{
can1=1;
}
}
if(judge(x+i,y-i))
{
if(mmap[x+i][y-i]=='K')
{
if(can2==0)
{
winb=1;
break;
}
}
else if(mmap[x+i][y-i]!='.')
can2=1;
}
}
if(winb==1)
break;
for(int i=1;i<=x-1;i++)
{
if(judge(x-i,y+i))
{
if(mmap[x-i][y+i]=='K')
{
if(can3==0)
{
winb=1;
break;
}
}
else if(mmap[x-i][y+i]!='.')
{
can3=1;
}
}
if(judge(x-i,y-i))
{
if(mmap[x-i][y-i]=='K')
{
if(can4==0)
{
winb=1;
break;
}
}
else if(mmap[x-i][y-i]!='.')
{
can4=1;
}
}
}
if(winb==1)
break;
break;
//如果是车的话
case 'r':for(int i=1;i<=x-1;i++) //向上
{
/* if(judge(x-i,y)==false)
continue;*/
if(mmap[x-i][y]=='K')
{
winb=1;
break;
}
else if(mmap[x-i][y]!='.')
break;
}
if(winb==1)
break;
for(int i=1;i<=8-x;i++) //向下
{
/*if(judge(x+i,y)==false)
continue;*/
if(mmap[x+i][y]=='K')
{
winb=1;
break;
}
else if(mmap[x+i][y]!='.')
break;
}
if(winb==1)
break;
for(int j=1;j<=y-1;j++) //向左
{
/* if(judge(x,y-j)==false)
continue;*/
if(mmap[x][y-j]=='K')
{
winb=1;
break;
}
else if(mmap[x][y-j]!='.')
break;
}
if(winb==1)
break;
for(int j=1;j<=8-y;j++)//向右
{
/* if(judge(x,y+j)==false)
continue;*/
if(mmap[x][y+j]=='K')
{
winb=1;
break;
}
else if(mmap[x][y+j]!='.')
break;
}
if(winb==1)
break;
break;
//如果是后的话
case 'q':
for(int i=1;i<=8-x;i++)
{
if(judge(x+i,y+i))
{
if(mmap[x+i][y+i]=='K')
{
if(can1==0)
{
winb=1;
break;
}
}
else if(mmap[x+i][y+i]!='.')
{
can1=1;
}
}
if(judge(x+i,y-i))
{
if(mmap[x+i][y-i]=='K')
{
if(can2==0)
{
winb=1;
break;
}
}
else if(mmap[x+i][y-i]!='.')
can2=1;
}
}
if(winb==1)
break;
for(int i=1;i<=x-1;i++)
{
if(judge(x-i,y+i))
{
if(mmap[x-i][y+i]=='K')
{
if(can3==0)
{
winb=1;
break;
}
}
else if(mmap[x-i][y+i]!='.')
{
can3=1;
}
}
if(judge(x-i,y-i))
{
if(mmap[x-i][y-i]=='K')
{
if(can4==0)
{
winb=1;
break;
}
}
else if(mmap[x-i][y-i]!='.')
{
can4=1;
}
}
}
if(winb==1)
break;
for(int i=1;i<=x-1;i++) //向上
{
/* if(judge(x-i,y)==false)
continue;*/
if(mmap[x-i][y]=='K')
{
winb=1;
break;
}
else if(mmap[x-i][y]!='.')
break;
}
if(winb==1)
break;
for(int i=1;i<=8-x;i++) //向下
{
/*if(judge(x+i,y)==false)
continue;*/
if(mmap[x+i][y]=='K')
{
winb=1;
break;
}
else if(mmap[x+i][y]!='.')
break;
}
if(winb==1)
break;
for(int j=1;j<=y-1;j++) //向左
{
/* if(judge(x,y-j)==false)
continue;*/
if(mmap[x][y-j]=='K')
{
winb=1;
break;
}
else if(mmap[x][y-j]!='.')
break;
}
if(winb==1)
break;
for(int j=1;j<=8-y;j++)//向右
{
/*if(judge(x,y+j)==false)
continue;*/
if(mmap[x][y+j]=='K')
{
winb=1;
break;
}
else if(mmap[x][y+j]!='.')
break;
}
if(winb==1)
break;
break;
}//switch
if(winb==1)
break;
}
if(winb==1)
{
printf("Game #%d: white king is in check.\n",++ca);
continue;
}
int wina=0;
for(int i=1;i<=numw;i++)
{
if(i==wk)
continue;
int can1=0,can2=0;
int can3=0,can4=0;
int x=white[i][1],y=white[i][2];
switch(mmap[x][y])
{
case 'P':if((judge(x-1,y-1)&&mmap[x-1][y-1]=='k')||(judge(x-1,y+1)&&mmap[x-1][y+1]=='k'))
{
wina=1;
break;
}
break;
case 'N':if((judge(x-1,y+2)&&mmap[x-1][y+2]=='k')||(judge(x+1,y+2)&&mmap[x+1][y+2]=='k'))
{
wina=1;
break;
}
if((judge(x-2,y+1)&&mmap[x-2][y+1]=='k')||(judge(x+2,y+1)&&mmap[x+2][y+1]=='k'))
{
wina=1;
break;
}
if((judge(x-2,y-1)&&mmap[x-2][y-1]=='k')||(judge(x+2,y-1)&&mmap[x+2][y-1]=='k'))
{
wina=1;
break;
}
if((judge(x-1,y-2)&&mmap[x-1][y-2]=='k')||(judge(x+1,y-2)&&mmap[x+1][y-2]=='k'))
{
wina=1;
break;
}
break;
case 'B':
for(int i=1;i<=8-x;i++)
{
if(judge(x+i,y+i))
{
if(mmap[x+i][y+i]=='k')
{
if(can1==0)
{
wina=1;
break;
}
}
else if(mmap[x+i][y+i]!='.')
{
can1=1;
}
}
if(judge(x+i,y-i))
{
if(mmap[x+i][y-i]=='k')
{
if(can2==0)
{
wina=1;
break;
}
}
else if(mmap[x+i][y-i]!='.')
can2=1;
}
}
if(wina==1)
break;
for(int i=1;i<=x-1;i++)
{
if(judge(x-i,y+i))
{
if(mmap[x-i][y+i]=='k')
{
if(can3==0)
{
wina=1;
break;
}
}
else if(mmap[x-i][y+i]!='.')
{
can3=1;
}
}
if(judge(x-i,y-i))
{
if(mmap[x-i][y-i]=='k')
{
if(can4==0)
{
wina=1;
break;
}
}
else if(mmap[x-i][y-i]!='.')
{
can4=1;
}
}
}
if(wina==1)
break;
break;
case 'R':for(int i=1;i<=x-1;i++) //向上
{
/*if(judge(x-i,y)==false)
continue;*/
if(mmap[x-i][y]=='k')
{
wina=1;
break;
}
else if(mmap[x-i][y]!='.')
break;
}
if(wina==1)
break;
for(int i=1;i<=8-x;i++) //向下
{
/*if(judge(x+i,y)==false)
continue;*/
if(mmap[x+i][y]=='k')
{
wina=1;
break;
}
else if(mmap[x+i][y]!='.')
break;
}
if(wina==1)
break;
for(int j=1;j<=y-1;j++) //向左
{
/*if(judge(x,y-j)==false)
continue;*/
if(mmap[x][y-j]=='k')
{
wina=1;
break;
}
else if(mmap[x][y-j]!='.')
break;
}
if(wina==1)
break;
for(int j=1;j<=8-y;j++)//向右
{
/*if(judge(x,y+j)==false)
continue;*/
if(mmap[x][y+j]=='k')
{
wina=1;
break;
}
else if(mmap[x][y+j]!='.')
break;
}
if(wina==1)
break;
break;
case 'Q':
for(int i=1;i<=8-x;i++)
{
if(judge(x+i,y+i))
{
if(mmap[x+i][y+i]=='k')
{
if(can1==0)
{
wina=1;
break;
}
}
else if(mmap[x+i][y+i]!='.')
{
can1=1;
}
}
if(judge(x+i,y-i))
{
if(mmap[x+i][y-i]=='k')
{
if(can2==0)
{
wina=1;
break;
}
}
else if(mmap[x+i][y-i]!='.')
can2=1;
}
}
if(wina==1)
break;
for(int i=1;i<=x-1;i++)
{
if(judge(x-i,y+i))
{
if(mmap[x-i][y+i]=='k')
{
if(can3==0)
{
wina=1;
break;
}
}
else if(mmap[x-i][y+i]!='.')
{
can3=1;
}
}
if(judge(x-i,y-i))
{
if(mmap[x-i][y-i]=='k')
{
if(can4==0)
{
wina=1;
break;
}
}
else if(mmap[x-i][y-i]!='.')
{
can4=1;
}
}
}
if(wina==1)
break;
for(int i=1;i<=x-1;i++) //向上
{
/*if(judge(x-i,y)==false)
continue;*/
if(mmap[x-i][y]=='k')
{
wina=1;
break;
}
else if(mmap[x-i][y]!='.')
break;
}
if(wina==1)
break;
for(int i=1;i<=8-x;i++) //向下
{
/*if(judge(x+i,y)==false)
continue;*/
if(mmap[x+i][y]=='k')
{
wina=1;
break;
}
else if(mmap[x+i][y]!='.')
break;
}
if(wina==1)
break;
for(int j=1;j<=y-1;j++) //向左
{
/*if(judge(x,y-j)==false)
continue;*/
if(mmap[x][y-j]=='k')
{
wina=1;
break;
}
else if(mmap[x][y-j]!='.')
break;
}
if(wina==1)
break;
for(int j=1;j<=8-y;j++)//向右
{
/*if(judge(x,y+j)==false)
continue;*/
if(mmap[x][y+j]=='k')
{
wina=1;
break;
}
else if(mmap[x][y+j]!='.')
break;
}
if(wina==1)
break;
break;
}//switch
if(wina==1)
break;
}
if(wina==1)
{
printf("Game #%d: black king is in check.\n",++ca);
continue;
}
if(wina==0&&winb==0&&flag)
printf("Game #%d: no king is in check.\n",++ca);
}while(flag);
return 0;
}