AcWing 1324. 五子棋 模拟 (2016 年清华大学计算机系推研)

地址 https://www.acwing.com/problem/content/description/1326/

小 A 和小 B 在下五子棋。

五子棋是在一个由网格构成的棋盘内进行的。

网格有 1515 列,共有 225 个交叉点。

小 A 先手执黑棋,小 B 后手执白棋。

两人轮流下棋,每次下棋都将一个自己的棋子放在棋盘上一个空白的交叉点上。

然而,由于小 A 和小 B 都不知道五子棋的胜利条件,所以即使有一方已经胜利了,他们仍然会继续下棋。

现在想请你帮忙分析一下,所下的棋局是在第几步结束的。

当然,也有可能他们最终仍然没有分出胜负,这时请判定他们平局。

五子棋的胜利条件是这样的:当同一行或同一列或同一斜线(即与网格线成 45° 角的直线)上连续的五个或五个以上交叉点放有同色棋子的时候,立即判定使用该颜色棋子的玩家获得胜利,游戏结束。

输入格式
第一行输入一个正整数 n,表示双方总共下了多少步棋。

接下来 n 行,每行两个正整数。其中,第 i 行的两个数 x,y 表示第 i 步的棋子下在了第 x 条横线和第 y 条竖线的交叉点上。若 i 为奇数,则这个棋子是黑棋,否则是白棋。

输出格式
若没有人获得胜利,你需要输出“Tie”(不含引号)。

否则,若小 A 获胜,输出 “A”(不含引号),若小 B 获胜,输出 “B”(不含引号);并输出一个正整数 w 表示第 w 步下完后游戏应当结束,字母与整数间用一个空格隔开。

数据范围
对于 20% 的数据,游戏结果是平局。
对于 30% 的数据,游戏在最后一手结束。
对于 100% 的数据,0≤n≤2251≤x,y≤15。

输入样例:
9
1 1
2 1
1 2
2 2
1 3
2 3
1 4
2 4
1 5
输出样例:
A 9

算法1
这是一道模拟题
主要是代码要简洁。
八个方向的检测是否连成五子可以精简成4个方向。
4个方向的检测可以使用for循环减少重复代码。
还需要一个检测x y是否在棋盘内的代码。

有了以上函数 代码可以简短不少

C++ 代码

#include <iostream>

using namespace std;

const int N = 15;
int board[N + 5][N + 5];
int n;
int winid = 0;

//0右 1 左 2下  3上 4右下 5左上 6下左 7右上
int xyAdd[8][2] = {
    {0,1},{0,-1},   //y+-
    {1,0},{-1,0},   //x+-
    {1,1},{-1,-1},  //xy+-
    {1,-1},{-1,1}   //x+- y-+
};

//检测是否是正确坐标 是则返回真
bool IsValidCoordinatesXY(int x, int y)
{
    if (x < 1 || x > N || y < 1 || y > N) return false;
    return true;
}


bool Check(int x, int y, int id)
{
    bool ret = false;

    int count = 1;
    for (int i = 0; i < 4; i++) {
        int lx = x; int ly = y; int rx = x; int ry = y;
        count = 1;
        lx += xyAdd[i * 2][0]; ly += xyAdd[i * 2][1];
        while (IsValidCoordinatesXY(lx, ly) && board[lx][ly] == id) {
            count++; lx += xyAdd[i * 2][0]; ly += xyAdd[i * 2][1];
        }
        rx += xyAdd[i * 2 + 1][0]; ry += xyAdd[i * 2 + 1][1];
        while (IsValidCoordinatesXY(rx, ry) && board[rx][ry] == id) {
            rx += xyAdd[i * 2 + 1][0]; ry += xyAdd[i * 2 + 1][1]; count++;
        }
        if (count >= 5) return true;
    }


    return false;
}

int main()
{
    cin >> n;

    for (int i = 1; i <= n; i++) {
        int x, y;
        cin >> x >> y;
        board[x][y] = i % 2 + 1;
        if (i > 8) {
            if (Check(x, y, i % 2 + 1)) {
                if (i % 2 == 1) { cout << "A " << i << endl; }
                else { cout << "B " << i << endl; }
                return 0;
            }
        }
    }

    cout << "Tie" << endl;
    return 0;
}

作者:itdef
链接:https://www.acwing.com/solution/content/19189/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

posted on 2020-08-24 16:51  itdef  阅读(326)  评论(0编辑  收藏  举报

导航