Codeforces3C. Tic-tac-toe 题解 状态压缩+搜索

题目链接:https://codeforces.com/contest/3/problem/C
题目大意:
有一个 \(3 \times 3\) 的棋盘,给你一个棋盘当前的状态,请你输出当前这个状态对应的描述。
解题思路:
\(3 \times 3\) 的棋盘上一共有9个位置,每个位置只有可能是3种状态:“.”、“0”或“X”。
所以总的状态数有 \(3^9\) 种,我们可以从初始状态开始来搜索遍历得到所有的状态对应的描述(如果一个状态通过搜索遍历不到,那么这个状态就是 illegal 的)。

代码解释

get_status_num():获得当前状态对应的状态码。
status与状态对应关系:
illegal -- 0
first -- 1
second -- 2
the first player won -- 3
the second player won -- 4
draw -- 5

check_who_win():判断当前状态谁赢

  • 返回1: the first win
  • 返回2:the second win
  • 返回0:还没有人赢

check_whos_turn():判断当前是应该谁下棋

  • 返回1:first
  • 返回2:second

最后我们从初始状态搜索一下,就能够得到所有的状态对应的描述。

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 20000; // 棋盘总共有3^9=19683种状态
char grid[3][4];
int status[maxn];
/**
status与状态对应关系
illegal -- 0
first   -- 1
second  -- 2
the first player won    -- 3
the second player won   -- 4
draw    -- 5
*/
/*
 * get_status_num()获得当前状态对应的状态码
*/
int get_status_num() {
    int t = 1, ans = 1;
    for (int i = 0; i < 3; i ++) {
        for (int j = 0; j < 3; j ++) {
            int a;
            switch (grid[i][j]) {
                case 'X': a = 1; break;
                case '0': a = 2; break;
                default: a = 0;
            }
            ans += a * t;
            t *= 3;
        }
    }
    return ans;
}
/*
 * check_who_win判断当前状态谁赢
 * 返回1: the first win
 * 返回2:the second win
 * 返回0:还没有人赢
*/
int check_who_win() {
    for (int i = 0; i < 3; i ++) {
        if (grid[i][0]!='.' && grid[i][0]==grid[i][1] && grid[i][0]==grid[i][2]) {
            return (grid[i][0] == 'X') ? 1 : 2;
        }
        if (grid[0][i]!='.' && grid[0][i]==grid[1][i] && grid[0][i]==grid[2][i]) {
            return (grid[0][i] == 'X') ? 1 : 2;
        }
    }
    for (int i = -1; i <= 1; i += 2) {
        if (grid[1][1]!='.' && grid[1][1]==grid[0][1-i] && grid[1][1]==grid[2][1+i]) {
            return (grid[1][1] == 'X') ? 1 : 2;
        }
    }
    return 0;
}
/*
 * check_whos_turn判断当前是应该谁下棋
 * 返回1:first
 * 返回2:second
*/
int check_whos_turn() {
    int cnt1 = 0, cnt2 = 0;
    for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++) if (grid[i][j] != '.') {
        if (grid[i][j] == 'X') cnt1 ++;
        else cnt2 ++;
    }
    if (cnt1 == cnt2) return 1;
    else return 2;
}

void init() {
    for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++) grid[i][j] = '.';
}

void dfs() {
    int status_num = get_status_num();
    int winner_id = check_who_win();
    if (winner_id) {
        status[status_num] = winner_id + 2;
    }
    else {
        int turn_id = check_whos_turn();
        status[status_num] = turn_id;
        char chess = (turn_id == 1) ? 'X' : '0';
        bool has_place_to_put = false;
        for (int i = 0; i < 3; i ++) {
            for (int j = 0; j < 3; j ++) {
                if (grid[i][j] == '.') {
                    has_place_to_put = true;
                    grid[i][j] = chess;
                    dfs();
                    grid[i][j] = '.';
                }
            }
        }
        if (!has_place_to_put) {
            status[status_num] = 5; // draw
        }
    }
}

int main() {
    init();
    dfs();
    for (int i = 0; i < 3; i ++) cin >> grid[i];
    string ans;
    switch (status[get_status_num()]) {
        case 0: ans = "illegal"; break;
        case 1: ans = "first"; break;
        case 2: ans = "second"; break;
        case 3: ans = "the first player won"; break;
        case 4: ans = "the second player won"; break;
        case 5: ans = "draw"; break;
        default: break;
    }
    cout << ans << endl;
    return 0;
}

原文地址:https://www.cnblogs.com/codedecision/p/11690983.html

时间: 2024-10-19 21:01:30

Codeforces3C. Tic-tac-toe 题解 状态压缩+搜索的相关文章

tic tac toe

井字棋 tic tac toe,布布扣,bubuko.com

amazon.设计1. tic tac toe

//不觉中 已经全力找工作好久好久了.大概有1年半了.身心疲惫,不要放弃.曙光快来了. 1.tic tac toe //http://www.ntu.edu.sg/home/ehchua/programming/java/JavaGame_TicTacToe.html 类似相关棋牌坐标对战游戏 一通百通 /** * Enumerations for the various states of the game */ public enum GameState { // to save as "G

HDU 1885 Key Task 状态压缩+搜索

点击打开链接 Key Task Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1176    Accepted Submission(s): 462 Problem Description The Czech Technical University is rather old - you already know that it c

Principle of Computing (Python)学习笔记(7) DFS Search + Tic Tac Toe use MiniMax Stratedy

1. Trees Tree is a recursive structure. 1.1 math nodes https://class.coursera.org/principlescomputing-001/wiki/view? page=trees 1.2 CODE无parent域的树 http://www.codeskulptor.org/#poc_tree.py class Tree: """ Recursive definition for trees plus

2019 GDUT Rating Contest III : Problem C. Team Tic Tac Toe

题面: C. Team Tic Tac Toe Input ?le: standard input Output ?le: standard output Time limit: 1 second Memory limit: 256 megabytes Farmer John owns 26 cows, which by happenstance all have names starting with different letters of the alphabet, so Farmer J

【leetcode】1275. Find Winner on a Tic Tac Toe Game

题目如下: Tic-tac-toe is played by two players A and B on a 3 x 3 grid. Here are the rules of Tic-Tac-Toe: Players take turns placing characters into empty squares (" "). The first player A always places "X" characters, while the second pl

POJ 1632 Vase collection【状态压缩+搜索】

题目传送门:http://poj.org/problem?id=1632 Vase collection Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2308   Accepted: 901 Description Mr Cheng is a collector of old Chinese porcelain, more specifically late 15th century Feng dynasty vase

ZOJ 3814 Sawtooth Puzzle 状态压缩搜索

由于一个框框只有4种状态,总状态数只有4^9,bfs可解. 麻烦的地方就在于模拟. 我的状态的存法是,将初始状态看做000000000,若顺时针旋转一次就+1, 3+1=0. bfs的过程中,需要套一个dfs计算旋转当前框框会影响到哪些框. 有个地方要注意,就是目标状态其实不止一种,因为有些框框旋转之后不变,我们必须把所有可能的目标状态都计算出来,样例的中间那个框框就是这种情况. #include <iostream> #include<cstdio> #include<al

UVa 10363 - Tic Tac Toe

题目:给你一个井字棋的状态,判断是否合法. 分析:枚举.直接枚举多有情况判断即可. 合法状态有三种情况:(X先下子) 1.X赢,则O不能赢,且X比O多一子: 2.O赢,则X不能赢,且O和X子一样多: 3.没人赢,此时O的子和可能和X一样多,也可能少一个. 说明:简单题(⊙_⊙). #include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include &l