这道有关象棋的题目是真的恶心,一个月之前做的时候w到怀疑人生。
主要集中 在下面几个方面,第一个就是一定要使用row,col而不要去使用x,y
第二个就是绝对不要使用scanf(“%c”),如果想要输入字符,直接用字符串代替就好
先来总结一下我自己的思路,
分别判断将军在四个可以走的位置上是不是安全的。
在判断的时候,先判断是不是在palace中(is_palace() 一般这种函数一定要单独的写出来包括is_in_board())
第二步,判断是否能被马吃掉,策略就是,在输入棋盘的时候,就更新了H_domain[][]数组,为1的地方就是马能吃到的地方。
第三步,判断是不是能被车将炮吃掉,之所以把他们放到一起,是因为他们的判断有联系,判断完车或者将后,可以接着判断炮
策略是,从紧邻这四个位置开始扫描,看是否能扫到字母,若扫到,判断是不是车或者将,如果是,那肯定这个位置不能待,如果不是,那么接着继续扫描,如果接着扫描的下一个棋子是炮,那么就不能待在这个地方。
以上就是所使用的思路,其实还有一个思路,就是一开始输入棋盘的时候,就把所有能被吃掉的地方domain[][]更新为1,这种情况适合棋子较少的情况,因为需要判读那的地方比较的少。
接下来贴出我的代码
#include<cstdio> #include<string> #include<cstring> #include<ctype.h> using namespace std; char board[11][10];//是使用row 1~10,col 1~9 int black_row,black_col; int H_domain[11][10];//马的控制范围 bool is_in_board(int row,int col) { if(row>=1&&row<=10&&col>=1&&col<=9) return true; return false; } bool initial() { memset(board,0,sizeof(board)); memset(H_domain,0,sizeof(H_domain)); int n; scanf("%d%d%d",&n,&black_row,&black_col);//绝对绝对不要使用scanf("%c") if(n==0) return false; for(int i=0;i<n;i++) { char A[3]; int r,c; scanf("%s%d%d",A,&r,&c); //printf("%c%d%d\n",A[0],r,c); board[r][c]=A[0]; } //下面是更新H_domain[][] for(int r=1;r<=10;r++) { for(int c=1;c<=9;c++) { if(board[r][c]=='H') { if(is_in_board(r,c-1)&&board[r][c-1]==0)//左面不别马腿 { if(is_in_board(r+1,c-2)) { H_domain[r+1][c-2]=1; } if(is_in_board(r-1,c-2)) { H_domain[r-1][c-2]=1; } } if(is_in_board(r,c+1)&&board[r][c+1]==0)//右面不别马腿 { if(is_in_board(r+1,c+2)) { H_domain[r+1][c+2]=1; } if(is_in_board(r-1,c+2)) { H_domain[r-1][c+2]=1; } } if(is_in_board(r-1,c)&&board[r-1][c]==0)//上面不别马腿 { if(is_in_board(r-2,c+1)) { H_domain[r-2][c+1]=1; } if(is_in_board(r-2,c-1)) { H_domain[r-2][c-1]=1; } } if(is_in_board(r+1,c)&&board[r+1][c]==0)//下面不别马腿 { if(is_in_board(r+2,c+1)) { H_domain[r+2][c+1]=1; } if(is_in_board(r+2,c-1)) { H_domain[r+2][c-1]=1; } } } } } return true; } bool is_in_palace(int row,int col) { if(row>=1&&row<=3&&col>=4&&col<=6) return true; return false; } bool is_captured_by_H(int row,int col) { if(H_domain[row][col]) return true; else return false; } void print_board() { printf("\n"); for(int r=1;r<=10;r++) { for(int c=1;c<=9;c++) { if(isalpha(board[r][c])) { printf("%3c",board[r][c]); } else printf("%3d",board[r][c]); } printf("\n"); } printf("\n"); } void print_H_domain() { printf("\n"); for(int r=1;r<=10;r++) { for(int c=1;c<=9;c++) { printf("%3d",H_domain[r][c]); } printf("\n"); } printf("\n"); } bool is_captured_by_R_G_C(int row,int col) { int exist=0; for(int r=row+1;r<=10;r++)//往下扫描 { if(!exist&&isalpha(board[r][col])) { if(board[r][col]=='G'||board[r][col]=='R') { //printf("%d%d向下遇到了车和将\n",row,col); return true; } else {//肯定是遇到了别的东西 exist=1; } } else if(exist&&isalpha(board[r][col])) { if(board[r][col]=='C') { //printf("%d%d向下遇到了炮\n",row,col); return true; } else break;//向下扫描是安全的 } } exist=0; for(int r=row-1;r>=1;r--)//往上扫描 { if(!exist&&isalpha(board[r][col])) { if(board[r][col]=='G'||board[r][col]=='R') { //printf("%d%d向上遇到了车和将\n",row,col); return true; } else {//肯定是遇到了别的东西 exist=1; } } else if(exist&&isalpha(board[r][col])) { if(board[r][col]=='C') { //printf("%d%d向上遇到了炮\n",row,col); return true; } else break;//向下扫描是安全的 } } exist=0; for(int c=col-1;c>=1;c--)//往左扫描 { if(!exist&&isalpha(board[row][c])) { if(board[row][c]=='R') { //printf("%d%d向左遇到了车\n",row,col); return true; } else {//肯定是遇到了别的东西 exist=1; } } else if(exist&&isalpha(board[row][c])) { if(board[row][c]=='C') { //printf("%d%d向左遇到了炮\n",row,col); return true; } else break;//向下扫描是安全的 } } exist=0; for(int c=col+1;c<=9;c++)//往左扫描 { if(!exist&&isalpha(board[row][c])) { if(board[row][c]=='R') { //printf("%d%d向右遇到了车\n",row,col); return true; } else {//肯定是遇到了别的东西 exist=1; } } else if(exist&&isalpha(board[row][c])) { if(board[row][c]=='C') { //printf("%d%d向右遇到了炮\n",row,col); return true; } else break;//向下扫描是安全的 } } return false; } //判断这个点能不能走 bool is_safe(int row,int col) { if(!is_in_palace(row,col)) { //printf("%d%d不在palace中\n",row,col); return false; } if(is_captured_by_R_G_C(row,col))//被车将炮吃掉 { //printf("%d%d被车炮吃掉了\n",row,col); return false; } if(is_captured_by_H(row,col))//被马吃掉 { //printf("%d%d被马吃掉了\n",row,col); return false; } return true; } int main() { #ifdef local freopen("input.txt","r",stdin); //freopen("out.txt","w",stdout); #endif while(initial()) { //print_board(); //print_H_domain(); if(is_safe(black_row,black_col-1)||is_safe(black_row,black_col+1)||is_safe(black_row-1,black_col)||is_safe(black_row+1,black_col)) { printf("NO\n");//no代表黑方还没有死 } else { printf("YES\n");//yes表示黑方已经死了 } } return 0; }
总之学到了两点:重复用的函数抽象出来,不要使用%c
调试很重要,有一些错误是无法在编程的时候看出来的,这个时候,必须要使用调试。有些错误是可以记录下来,防止下次再错的,比如说&A,%c等。