zoukankan      html  css  js  c++  java
  • 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
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    Linux内核RPC请求过程
    二分图
    Java实现 蓝桥杯 算法提高 合并石子
    Java实现 蓝桥杯 算法提高 合并石子
    Java实现 蓝桥杯 算法提高 摩尔斯电码
    Java实现 蓝桥杯 算法提高 摩尔斯电码
    Java实现 蓝桥杯 算法提高 文本加密
    Java实现 蓝桥杯 算法提高 文本加密
    Java蓝桥杯 算法提高 九宫格
    Java蓝桥杯 算法提高 九宫格
  • 原文地址:https://www.cnblogs.com/itdef/p/13554806.html
Copyright © 2011-2022 走看看