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