220 - Othello (UVA)

题目链接如下:

Online Judge

我最终的代码如下(有个细节,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;
}

你可能感兴趣的:(UVA,算法)