348. Design Tic-Tac-Toe

LeetCode medium оригинал: C# #array #csharp #design #leetcode #math #medium #queue #string

Предположим, что следующие правила относятся к игре в крестики-нолики на доске размером n x n между двумя игроками:

Ход гарантированно является допустимым и делается на пустом поле.

Как только достигается выигрышное условие, дальнейшие ходы запрещены.

Игрок, который успешно размещает n своих меток в горизонтальном, вертикальном или диагональном ряду, выигрывает игру.

Реализуйте класс TicTacToe:

TicTacToe(int n) Инициализирует объект с размером доски n.

int move(int row, int col, int player) Указывает, что игрок с идентификатором player делает ход в ячейке (row, col) на доске. Ход гарантированно является допустимым, и два игрока ходят по очереди. Возвращает:

0, если после хода победителя нет.

1, если после хода игрок 1 является победителем.

2, если после хода игрок 2 является победителем.

Пример

Input

["TicTacToe", "move", "move", "move", "move", "move", "move", "move"]

[[3], [0, 0, 1], [0, 2, 2], [2, 2, 1], [1, 1, 2], [2, 0, 1], [1, 0, 2], [2, 1, 1]]

Output

[null, 0, 0, 0, 0, 0, 0, 1]

C# решение

сопоставлено/оригинал
public class TicTacToe {
    private int[] rows;
    private int[] cols;
    private int diagonal;
    private int antiDiagonal;
    private int n;
    public TicTacToe(int n) {
        this.n = n;
        rows = new int[n];
        cols = new int[n];
        diagonal = 0;
        antiDiagonal = 0;
    }
    public int Move(int row, int col, int player) {
        int add = (player == 1) ? 1 : -1;
        rows[row] += add;
        cols[col] += add;
        if (row == col) {
            diagonal += add;
        }
        if (row + col == n - 1) {
            antiDiagonal += add;
        }
        if (Math.Abs(rows[row]) == n || Math.Abs(cols[col]) == n || Math.Abs(diagonal) == n || Math.Abs(antiDiagonal) == n) {
            return player;
        }
        return 0;
    }
}

C++ решение

auto-draft, проверить перед отправкой
#include <bits/stdc++.h>
using namespace std;

// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
public class TicTacToe {
    private vector<int>& rows;
    private vector<int>& cols;
    private int diagonal;
    private int antiDiagonal;
    private int n;
    public TicTacToe(int n) {
        this.n = n;
        rows = new int[n];
        cols = new int[n];
        diagonal = 0;
        antiDiagonal = 0;
    }
    public int Move(int row, int col, int player) {
        int add = (player == 1) ? 1 : -1;
        rows[row] += add;
        cols[col] += add;
        if (row == col) {
            diagonal += add;
        }
        if (row + col == n - 1) {
            antiDiagonal += add;
        }
        if (abs(rows[row]) == n || abs(cols[col]) == n || abs(diagonal) == n || abs(antiDiagonal) == n) {
            return player;
        }
        return 0;
    }
}

Java решение

auto-draft, проверить перед отправкой
import java.util.*;
import java.math.*;

// Auto-generated Java draft from the C# solution. Review API differences before LeetCode submit.
public class TicTacToe {
    private int[] rows;
    private int[] cols;
    private int diagonal;
    private int antiDiagonal;
    private int n;
    public TicTacToe(int n) {
        this.n = n;
        rows = new int[n];
        cols = new int[n];
        diagonal = 0;
        antiDiagonal = 0;
    }
    public int Move(int row, int col, int player) {
        int add = (player == 1) ? 1 : -1;
        rows[row] += add;
        cols[col] += add;
        if (row == col) {
            diagonal += add;
        }
        if (row + col == n - 1) {
            antiDiagonal += add;
        }
        if (Math.abs(rows[row]) == n || Math.abs(cols[col]) == n || Math.abs(diagonal) == n || Math.abs(antiDiagonal) == n) {
            return player;
        }
        return 0;
    }
}

JavaScript решение

сопоставлено/оригинал
class TicTacToe {
    constructor(n) {
        this.n = n;
        this.rows = Array(n).fill(0);
        this.cols = Array(n).fill(0);
        this.diagonal = 0;
        this.antiDiagonal = 0;
    }

    move(row, col, player) {
        const add = player === 1 ? 1 : -1;
        this.rows[row] += add;
        this.cols[col] += add;
        if (row === col) {
            this.diagonal += add;
        }
        if (row + col === this.n - 1) {
            this.antiDiagonal += add;
        }
        if (Math.abs(this.rows[row]) === this.n || 
            Math.abs(this.cols[col]) === this.n || 
            Math.abs(this.diagonal) === this.n || 
            Math.abs(this.antiDiagonal) === this.n) {
            return player;
        }
        return 0;
    }
}

Python решение

сопоставлено/оригинал
class TicTacToe:
    def __init__(self, n: int):
        self.n = n
        self.rows = [0] * n
        self.cols = [0] * n
        self.diagonal = 0
        self.anti_diagonal = 0

    def move(self, row: int, col: int, player: int) -> int:
        add = 1 if player == 1 else -1

        self.rows[row] += add
        self.cols[col] += add
        if row == col:
            self.diagonal += add
        if row + col == self.n - 1:
            self.anti_diagonal += add

        if (abs(self.rows[row]) == self.n or
            abs(self.cols[col]) == self.n or
            abs(self.diagonal) == self.n or
            abs(self.anti_diagonal) == self.n):
            return player

        return 0

Go решение

сопоставлено/оригинал
type TicTacToe struct {
    rows        []int
    cols        []int
    diagonal    int
    antiDiagonal int
    n           int
}

func Constructor(n int) TicTacToe {
    return TicTacToe{
        rows:        make([]int, n),
        cols:        make([]int, n),
        diagonal:    0,
        antiDiagonal: 0,
        n:           n,
    }
}

func (this *TicTacToe) Move(row int, col int, player int) int {
    add := 1
    if player == 2 {
        add = -1
    }

    this.rows[row] += add
    this.cols[col] += add
    if row == col {
        this.diagonal += add
    }
    if row+col == this.n-1 {
        this.antiDiagonal += add
    }

    if abs(this.rows[row]) == this.n || abs(this.cols[col]) == this.n || abs(this.diagonal) == this.n || abs(this.antiDiagonal) == this.n {
        return player
    }
    return 0
}

func abs(a int) int {
    if a < 0 {
        return -a
    }
    return a
}

Algorithm

Инициализация:

Создайте массивы rows и cols для отслеживания количества маркеров в каждой строке и столбце соответственно.

Создайте переменные diagonal и antiDiagonal для отслеживания количества маркеров на главной и побочной диагоналях соответственно.

Инициализируйте размер доски n.

Выполнение хода:

Увеличьте счетчики в rows, cols, diagonal и antiDiagonal в зависимости от текущего хода.

Если текущий ход игрока попадает на диагонали, обновите соответствующие переменные diagonal и antiDiagonal.

Проверка победы:

Проверьте, достиг ли один из счетчиков в rows, cols, diagonal или antiDiagonal значения n (размер доски). Если да, верните идентификатор игрока как победителя.

Если ни одно из условий победы не выполнено, верните 0, что означает отсутствие победителя после текущего хода.

😎

Вакансии для этой задачи

Показаны активные вакансии с пересечением по тегам задачи.

Все вакансии
Активных вакансий пока нет.