小红的夹吃棋

思路

这道题在说什么?给你一个棋盘,上面有黑子(o,小红执)和白子(*,小紫执),要你判断谁的棋子被"夹吃"了。

什么叫夹吃?就是一颗棋子在横向或纵向上,左右(或上下)紧挨着的都是对方棋子——三连珠,中间那颗就被吃了。

那胜负怎么判?

  • 只有一方的棋子被夹吃了,另一方赢
  • 双方都被吃了,或者都没被吃,平局

具体做法

  1. 读入 的棋盘(第一行的长度就是
  2. 遍历每个格子,如果是棋子(不是 .),检查它是否被夹吃:

- 水平方向:左边和右边都是对方棋子?

- 垂直方向:上边和下边都是对方棋子?

  1. 分别记录黑子(o)和白子(*)是否有被夹吃的情况
  2. 根据结果输出:只有白子被吃 → yukari(小红赢),只有黑子被吃 → kou(小紫赢),其他 → draw

注意一个坑:题目里 o 是小红的黑子,* 是小紫的白子,别搞反了。

代码

#include <bits/stdc++.h>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;

    while(T--){
        string firstRow;
        cin >> firstRow;
        int n = firstRow.size();

        vector<string> board(n);
        board[0] = firstRow;
        for(int i = 1; i < n; i++) cin >> board[i];

        bool blackCaptured = false, whiteCaptured = false;

        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                char c = board[i][j];
                if(c == '.') continue;
                char opp = (c == 'o') ? '*' : 'o';

                // 水平夹吃:左右都是对方
                if(j > 0 && j < n-1 && board[i][j-1] == opp && board[i][j+1] == opp){
                    if(c == 'o') blackCaptured = true;
                    else whiteCaptured = true;
                }
                // 垂直夹吃:上下都是对方
                if(i > 0 && i < n-1 && board[i-1][j] == opp && board[i+1][j] == opp){
                    if(c == 'o') blackCaptured = true;
                    else whiteCaptured = true;
                }
            }
        }

        if(blackCaptured && whiteCaptured) cout << "draw\n";
        else if(blackCaptured) cout << "kou\n";
        else if(whiteCaptured) cout << "yukari\n";
        else cout << "draw\n";
    }
    return 0;
}
import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine().trim());
        StringBuilder sb = new StringBuilder();

        while (T-- > 0) {
            String firstRow = br.readLine().trim();
            int n = firstRow.length();
            String[] board = new String[n];
            board[0] = firstRow;
            for (int i = 1; i < n; i++) board[i] = br.readLine().trim();

            boolean blackCap = false, whiteCap = false;

            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    char c = board[i].charAt(j);
                    if (c == '.') continue;
                    char opp = (c == 'o') ? '*' : 'o';

                    // 水平夹吃
                    if (j > 0 && j < n-1 && board[i].charAt(j-1) == opp && board[i].charAt(j+1) == opp) {
                        if (c == 'o') blackCap = true; else whiteCap = true;
                    }
                    // 垂直夹吃
                    if (i > 0 && i < n-1 && board[i-1].charAt(j) == opp && board[i+1].charAt(j) == opp) {
                        if (c == 'o') blackCap = true; else whiteCap = true;
                    }
                }
            }

            if (blackCap && whiteCap) sb.append("draw\n");
            else if (blackCap) sb.append("kou\n");
            else if (whiteCap) sb.append("yukari\n");
            else sb.append("draw\n");
        }
        System.out.print(sb);
    }
}
import sys
input = sys.stdin.readline

T = int(input())
out = []
for _ in range(T):
    first_row = input().strip()
    n = len(first_row)
    board = [first_row]
    for i in range(1, n):
        board.append(input().strip())

    black_cap = False
    white_cap = False

    for i in range(n):
        for j in range(n):
            c = board[i][j]
            if c == '.':
                continue
            opp = '*' if c == 'o' else 'o'
            # 水平夹吃
            if 0 < j < n - 1 and board[i][j-1] == opp and board[i][j+1] == opp:
                if c == 'o':
                    black_cap = True
                else:
                    white_cap = True
            # 垂直夹吃
            if 0 < i < n - 1 and board[i-1][j] == opp and board[i+1][j] == opp:
                if c == 'o':
                    black_cap = True
                else:
                    white_cap = True

    if black_cap and white_cap:
        out.append("draw")
    elif black_cap:
        out.append("kou")
    elif white_cap:
        out.append("yukari")
    else:
        out.append("draw")

print('\n'.join(out))
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin });
const lines = [];
rl.on('line', line => lines.push(line.trim()));
rl.on('close', () => {
    let idx = 0;
    const T = parseInt(lines[idx++]);
    const res = [];
    for (let t = 0; t < T; t++) {
        const firstRow = lines[idx++];
        const n = firstRow.length;
        const board = [firstRow];
        for (let i = 1; i < n; i++) board.push(lines[idx++]);

        let blackCap = false, whiteCap = false;
        for (let i = 0; i < n; i++) {
            for (let j = 0; j < n; j++) {
                const c = board[i][j];
                if (c === '.') continue;
                const opp = c === 'o' ? '*' : 'o';
                if (j > 0 && j < n-1 && board[i][j-1] === opp && board[i][j+1] === opp) {
                    if (c === 'o') blackCap = true; else whiteCap = true;
                }
                if (i > 0 && i < n-1 && board[i-1][j] === opp && board[i+1][j] === opp) {
                    if (c === 'o') blackCap = true; else whiteCap = true;
                }
            }
        }

        if (blackCap && whiteCap) res.push("draw");
        else if (blackCap) res.push("kou");
        else if (whiteCap) res.push("yukari");
        else res.push("draw");
    }
    console.log(res.join('\n'));
});

复杂度

  • 时间:,每个棋盘遍历一遍
  • 空间:,存棋盘

总结

纯模拟题,没有什么算法技巧。就是遍历棋盘每个格子,看它有没有被左右或上下的对方棋子夹住。唯一要注意的是字符和角色的对应关系别搞混,以及边界判断(第一行/最后一行/第一列/最后一列的棋子不可能在那个方向上被夹吃)。