题目链接如下:
我最终的代码如下(有个细节,88行输出时,需要%2d;locate函数第三个参数是0的话,代表只是判断是否可以放置;1代表下一步棋,包括替换被夹住的棋子):
- #include
- #include
- // #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 debug
- freopen("0.txt","r",stdin);
- freopen("1.txt","w",stdout);
- #endif
- scanf("%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 debug
- fclose(stdin);
- fclose(stdout);
- #endif
- return 0;
- }
一开始把判断能否放置棋子的函数和下一步棋的函数分开来写,代码如下:
- #include
- #include
- // #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 debug
- freopen("0.txt","r",stdin);
- freopen("1.txt","w",stdout);
- #endif
- scanf("%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 debug
- fclose(stdin);
- fclose(stdout);
- #endif
- return 0;
- }