题目链接如下:
Online Judge
我最终的代码如下(有个细节,88行输出时,需要%2d;locate函数第三个参数是0的话,代表只是判断是否可以放置;1代表下一步棋,包括替换被夹住的棋子):
#include <cstdio>
#include <algorithm>
// #define debug
const int sz = 10;int n, sum, xx, yy;
char board[sz][sz];
char op[4];
char curr, other;
int dirX[] = {1, 1, 0, -1, -1, -1, 0, 1};
int dirY[] = {0, 1, 1, 1, 0, -1, -1, -1};int locate(int u, int v, int k){if(k == 0 && (board[u][v] == 'W' || board[u][v] == 'B')){return 0;}if(k == 1){board[u][v] = curr;}for(int i = 0; i < 8; ++i){for(int len = 1; len < 8; ++len){if(u + len * dirX[i] < 1 || u + len * dirX[i] > 8 || v + len * dirY[i] < 1 || v + len * dirY[i] > 8){break;}if(board[u + len * dirX[i]][v + len * dirY[i]] == curr){if(len == 1){break;}if(k == 0){return 1;}for(int j = 1; j < len; ++j){board[u + j * dirX[i]][v + j * dirY[i]] = curr;}break;}if(board[u + len * dirX[i]][v + len * dirY[i]] == '-'){break;}}}return 0;
}int main(){#ifdef debugfreopen("0.txt","r",stdin);freopen("1.txt","w",stdout);#endifscanf("%d\n", &n);for(int kase = 0; kase < n; ++kase){if(kase){printf("\n");}for(int i = 1; i <= 8; ++i){scanf("%s", board[i] + 1);}scanf("%s", op);curr = op[0];other = (curr == 'B' ? 'W' : 'B');while(scanf("%s", op)){if(op[0] == 'L'){sum = 0;for(int i = 1; i <= 8; ++i){for(int j = 1; j <= 8; ++j){if(locate(i, j, 0)){printf("%s(%d,%d)", sum ? " " : "", i, j);sum++;}}}printf("%s", sum ? "\n" : "No legal move.\n");} else if(op[0] == 'M'){if(!locate(op[1] - '0', op[2] - '0', 0)){std::swap(curr, other);}locate(op[1] - '0', op[2] - '0', 1);xx = yy = 0;for(int i = 1; i <= 8; ++i){for(int j = 1; j <= 8; ++j){if(board[i][j] == 'B'){xx++;} else if(board[i][j] == 'W'){yy++;}}}printf("Black - %2d White - %2d\n", xx, yy);std::swap(curr, other);} else{for(int i = 1; i <= 8; ++i){printf("%s\n", board[i] + 1);}break;}}}#ifdef debugfclose(stdin);fclose(stdout);#endifreturn 0;
}
一开始把判断能否放置棋子的函数和下一步棋的函数分开来写,代码如下:
#include <cstdio>
#include <algorithm>
// #define debug
const int sz = 10;int n, sum, xx, yy;
char board[sz][sz];
char op[4];
char curr, other;
int dirX[] = {1, 1, 0, -1, -1, -1, 0, 1};
int dirY[] = {0, 1, 1, 1, 0, -1, -1, -1};bool canLocate(int u, int v){if(board[u][v] == 'W' || board[u][v] == 'B'){return false;}for(int i = 0; i < 8; ++i){for(int len = 1; len < 8; ++len){if(u + len * dirX[i] < 1 || u + len * dirX[i] > 8 || v + len * dirY[i] < 1 || v + len * dirY[i] > 8){break;}if(board[u + len * dirX[i]][v + len * dirY[i]] == curr){if(len == 1){break;}return true;}if(board[u + len * dirX[i]][v + len * dirY[i]] == '-'){break;}}}return false;
}void locate(int u, int v){board[u][v] = curr;for(int i = 0; i < 8; ++i){for(int len = 1; len < 8; ++len){if(u + len * dirX[i] < 1 || u + len * dirX[i] > 8 || v + len * dirY[i] < 1 || v + len * dirY[i] > 8){break;}if(board[u + len * dirX[i]][v + len * dirY[i]] == curr){if(len == 1){break;}for(int j = 1; j < len; ++j){board[u + j * dirX[i]][v + j * dirY[i]] = curr;}break;}if(board[u + len * dirX[i]][v + len * dirY[i]] == '-'){break;}}}
}int main(){#ifdef debugfreopen("0.txt","r",stdin);freopen("1.txt","w",stdout);#endifscanf("%d\n", &n);for(int kase = 0; kase < n; ++kase){if(kase){printf("\n");}for(int i = 1; i <= 8; ++i){scanf("%s", board[i] + 1);}scanf("%s", op);curr = op[0];other = (curr == 'B' ? 'W' : 'B');while(scanf("%s", op)){if(op[0] == 'L'){sum = 0;for(int i = 1; i <= 8; ++i){for(int j = 1; j <= 8; ++j){if(canLocate(i, j)){printf("%s(%d,%d)", sum ? " " : "", i, j);sum++;}}}printf("%s", sum ? "\n" : "No legal move.\n");} else if(op[0] == 'M'){if(!canLocate(op[1] - '0', op[2] - '0')){std::swap(curr, other);}locate(op[1] - '0', op[2] - '0');xx = yy = 0;for(int i = 1; i <= 8; ++i){for(int j = 1; j <= 8; ++j){if(board[i][j] == 'B'){xx++;} else if(board[i][j] == 'W'){yy++;}}}printf("Black - %2d White - %2d\n", xx, yy);std::swap(curr, other);} else{for(int i = 1; i <= 8; ++i){printf("%s\n", board[i] + 1);}break;}}}#ifdef debugfclose(stdin);fclose(stdout);#endifreturn 0;
}