> For the complete documentation index, see [llms.txt](https://hao-fu-1.gitbook.io/oj/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hao-fu-1.gitbook.io/oj/string/794.-valid-tic-tac-toe-state.md).

# 794. Valid Tic-Tac-Toe State

https\://leetcode.com/problems/valid-tic-tac-toe-state/

检验给定的三子棋状态是否合法，X为先手。因为X为先手，当X的数目不等于O或比多1时不合法。当统计得出X是取胜时，O的数目与X的数目一致，说明X已经赢了O还在下，不合法。当得出O取胜时，X不可能也是胜的且X的数目应与O数目一致。

```cpp
/*
 * @lc app=leetcode id=794 lang=cpp
 *
 * [794] Valid Tic-Tac-Toe State
 */

// @lc code=start
class Solution {
public:
    bool validTicTacToe(vector<string>& board) {
        vector<int> r(3), c(3);
        int xc = 0, oc = 0, diag = 0, adiag = 0;
        bool xwin = false, owin = false;
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 3; ++j) {
                if (board[i][j] == 'X') {
                    ++xc;
                    ++r[i];
                    ++c[j];
                    if (i == j) ++diag;
                    if (i == 2 - j) ++adiag;
                } else if (board[i][j] == 'O') {
                    ++oc;
                    --r[i];
                    --c[j];
                    if (i == j) --diag;
                    if (i == 2 - j) --adiag;
                }
                if (r[i] == 3 || c[j] == 3 || diag == 3 || adiag == 3) {
                    xwin = true;
                } else if (r[i] == -3 || c[j] == -3 || diag == -3 || adiag == -3) {
                    owin = true;
                }
            }
        }

        if (!(xc == oc || xc == oc + 1)) return false;
        if (xwin && xc == oc) return false;
        if (owin && (xwin || xc == oc + 1)) return false;
        return true;
    }
};
// @lc code=end


```
