1. 程式人生 > >Othello, ACM/ICPC World Finals 1992

Othello, ACM/ICPC World Finals 1992

  • 模擬
  • 思路:
    • 依次模擬3種指令
  • 注意:
    • Make a move指令輸出的格式是‘Black - xx White - yy’1
    • 統計棋子的個數時,要不重不漏。當然,也可以每次遍歷棋盤,統計個數,這種方法可以減少錯誤
    • 函式可以替代重複程式碼
#include <iostream>
#include <cstdio>
#include <set>
#include <cstring>
using namespace std;
char board[9][9];
typedef pair<int, int> Pint;
set<
Pint> pm; int piece[2]; bool inBoard(int r, int c) { return 1 <= r && r <= 8 && 1 <= c && c <= 8; } bool isPossibleLine(int r, int c, int dr, int dc, const char &cur, const char &curPlayer) { r += dr; c += dc; while (inBoard(r, c) &&
board[r][c] == cur) { r += dr; c += dc; if (inBoard(r, c) && board[r][c] == curPlayer) { return true; } } return false; } bool isPossibleMove(const int &r0, const int &c0, const bool &isB) { if (board[r0][c0] != '-'
) return false; char cur = 'B'; char curPlayer = 'W'; if (isB) { cur = 'W'; curPlayer = 'B'; } for (int dr = -1; dr <= 1; ++dr) for (int dc = -1; dc <= 1; ++dc) { if (dr == 0 && dc == 0) continue; if (isPossibleLine(r0, c0, dr, dc, cur, curPlayer)) return true; } return false; } bool makeAMove(const int &r0, const int &c0, bool isB) { char cur = 'B', curPlayer = 'W'; if (isB) { cur = 'W'; curPlayer = 'B'; } bool okCurPlayer = false; for (int dr = -1; dr <= 1; ++dr) for (int dc = -1; dc <= 1; ++dc) { if (dr == 0 && dc == 0) continue; // bool okLine = false; if (isPossibleLine(r0, c0, dr, dc, cur, curPlayer)) { okCurPlayer = true; board[r0][c0] = curPlayer; int r = r0 + dr, c = c0 + dc; while (board[r][c] == cur) { piece[isB]++; piece[!isB]--; board[r][c] = curPlayer; r += dr; c += dc; } } } if (okCurPlayer) { piece[isB]++; } else { char temp = cur; cur = curPlayer; curPlayer = temp; isB = !isB; piece[isB]++; for (int dr = -1; dr <= 1; ++dr) for (int dc = -1; dc <= 1; ++dc) { if (dr == 0 && dc == 0) continue; // bool okLine = false; if (isPossibleLine(r0, c0, dr, dc, cur, curPlayer)) { board[r0][c0] = curPlayer; int r = r0 + dr, c = c0 + dc; while (board[r][c] == cur) { piece[isB]++; piece[!isB]--; board[r][c] = curPlayer; r += dr; c += dc; } } } } return !isB; } int main() { int T; bool first = true; cin >> T; while (T--) { if (first) first = false; else cout << endl; pm.clear(); memset(piece, 0, sizeof(piece)); for (int r = 1; r <= 8; ++r) for (int c = 1; c <= 8; ++c) { cin >> board[r][c]; if (board[r][c] == 'W') piece[0]++; else if (board[r][c] == 'B') piece[1]++; } char curPlayer; bool isB = false; cin >> curPlayer; if (curPlayer == 'B') isB = true; char p[4]; while (cin >> p) { // cout << p << endl; if (p[0] == 'L') { // int cnt = 0; pm.clear(); for (int r = 1; r <= 8; ++r) for (int c = 1; c <= 8; ++c) { if (board[r][c] != '-') continue; // cout << "here!" << endl; if (isPossibleMove(r, c, isB)) pm.insert(Pint(r, c)); } for (auto it = pm.begin(); it != pm.end(); ++it) { if (it != pm.begin()) cout << " "; cout << '(' << it->first << ',' << it->second << ")"; } if (pm.size() == 0) cout << "No legal move."; cout << endl; } if (p[0] == 'M') { int r = p[1] - '0', c = p[2] - '0'; isB = makeAMove(r, c, isB); printf("Black - %2d White - %2d\n", piece[1], piece[0]); // printf("%d %d\n", piece[1], piece[0]); // cout << "Black - " << piece[1] << " White - " << piece[0] << endl; } if (p[0] == 'Q') { for (int r = 1; r <= 8; r++) { for (int c = 1; c <= 8; ++c) cout << board[r][c]; cout << endl; } break; } } } return 0; }
  1. 如果棋盤上某顏色棋子的個數是個位數,則要在十位處空出一格。 ↩︎