题目链接:
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; }