阿里笔试题:小红的四子棋

2022年4月15日阿里笔试题

(回忆)

小红和小紫下四子棋,现在给一个棋盘的状态,判断当前是否有人赢了,或者是还未分胜负。当一方有四个棋子连成一横或者一竖或者斜对角线时获胜。

输入:

第一行两个数字空格隔开,表示棋盘行数 n 和列数 m 。 后面跟着 n 行,每行 m 个字符,表示棋盘每个位置的状态。

其中 ‘.’ 表示没有放棋子的空位置,‘r’ 表示小红下的棋子,‘p’ 表示小紫下的棋子。

输出:

当前棋盘的状态。如果小红赢了,输出 “kou” ;如果小紫赢了,输出 “yukari” ;如果还没分出胜负,输出 “to be continued” 。


【拙劣解法,欢迎指教】

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String nm = in.nextLine();
            int n = Integer.parseInt(nm.split(" ")[0]);
            int m = Integer.parseInt(nm.split(" ")[1]);
            char[][] chess = new char[n][m];
            for (int i = 0; i < n; i++) {
                String inStr = in.nextLine();
                for (int j = 0; j < m; j++) {
                    chess[i][j] = inStr.charAt(j);
                }
            }

            System.out.println(check(chess, n, m));
        }
    }

    private static String check(char[][] chess, int n, int m) {
        int[][] lr = new int[n][m]; // 当前位置左边有多少个连续的 'r'
        int[][] ur = new int[n][m]; // 当前位置上边有多少个连续的 'r'
        int[][] lur = new int[n][m]; // 当前位置左上边有多少个连续的 'r'
        int[][] ldr = new int[n][m]; // 当前位置左下边有多少个连续的 'r'

        int[][] lp = new int[n][m]; // 当前位置左边有多少个连续的 'p'
        int[][] up = new int[n][m]; // 当前位置上边有多少个连续的 'p'
        int[][] lup = new int[n][m]; // 当前位置左上边有多少个连续的 'p'
        int[][] ldp = new int[n][m]; // 当前位置左下边有多少个连续的 'p'

        // 左边、上边、左上边
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (chess[i][j] == 'r') {
                    lr[i][j] = 1;
                    ur[i][j] = 1;
                    lur[i][j] = 1;
                    if (i > 0) {
                        ur[i][j] += ur[i - 1][j];
                    }
                    if (j > 0) {
                        lr[i][j] += lr[i][j - 1];
                    }
                    if (i > 0 && j > 0) {
                        lur[i][j] += lur[i - 1][j - 1];
                    }
                    if (lr[i][j] == 4 || ur[i][j] == 4 || lur[i][j] == 4) {
                        return "kou";
                    }
                } else if (chess[i][j] == 'p') {
                    lp[i][j] = 1;
                    up[i][j] = 1;
                    lup[i][j] = 1;
                    if (i > 0) {
                        up[i][j] += up[i - 1][j];
                    }
                    if (j > 0) {
                        lp[i][j] += lp[i][j - 1];
                    }
                    if (i > 0 && j > 0) {
                        lup[i][j] += lup[i - 1][j - 1];
                    }
                    if (lp[i][j] == 4 || up[i][j] == 4 || lup[i][j] == 4) {
                        return "yukari";
                    }
                }
            }
        }

        // 左下边的要单独算
        for (int i = n - 1; i >= 0; i--) {
            for (int j = 0; j < m; j++) {
                if (chess[i][j] == 'r') {
                    ldr[i][j] = 1;
                    if (i < n - 1 && j > 0) {
                        ldr[i][j] += ldr[i + 1][j - 1];
                    }
                    if (ldr[i][j] == 4) {
                        return "kou";
                    }
                } else if (chess[i][j] == 'p') {
                    ldp[i][j] = 1;
                    if (i < n - 1 && j > 0) {
                        ldp[i][j] += ldp[i + 1][j - 1];
                    }
                    if (ldp[i][j] == 4) {
                        return "yukari";
                    }
                }
            }
        }

        return "to be continued";
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值