zoukankan      html  css  js  c++  java
  • 洛谷P2346 四子连棋 题解 迭代加深搜索

    题目链接:https://www.luogu.com.cn/problem/P2346

    首先需要注意 题目描述 中说道的这句话:

    黑白双方交替走棋,任意一方可以先走

    然后我这边用的是迭代加深搜索解决的这个问题。

    我觉得 迭代加深搜索 结合了 DFSBFS 的优点:

    1. 能够像BFS一样进行层次遍历;
    2. 使用回溯,相比BFS将所有状态都加入队列,迭代加深搜索更省空间。

    示例代码:

    #include <bits/stdc++.h>
    using namespace std;
    char maze[5][5];
    inline bool in_map(int x, int y) {
        return x >= 0 && x < 4 && y >= 0 && y < 4;
    }
    int dir[4][2] = { -1, 0, 1, 0, 0, -1, 0, 1 }, D;
    void test(int d) {
        static int cnt = 0;
        cnt ++;
        // if (cnt % 10 == 0) _sleep(1000 * 100);
        cout << d << " :" << endl;
        for (int i = 0; i < 4; i ++) cout << maze[i] << endl;
    }
    bool check() {  // 用于判断是否已存在合法状态
        for (int i = 0; i < 4; i ++) {
            bool flag = true;
            for (int j = 1; j < 4; j ++) {  // 同一行
                if (maze[i][j] != maze[i][0]) {
                    flag = false;
                    break;
                }
            }
            if (flag) return true;
            flag = true;
            for (int j = 1; j < 4; j ++) {  // 同一列
                if (maze[j][i] != maze[0][i]) {
                    flag = false;
                    break;
                }
            }
            if (flag) return true;
        }
        bool flag = true;
        for (int i = 1; i < 4; i ++) {  // 对角线
            if (maze[i][i] != maze[0][0]) {
                flag = false;
                break;
            }
        }
        if (flag) return true;
        flag = true;
        for (int i = 1; i < 4; i ++) {  // 斜对角线
            if (maze[i][3-i] != maze[0][3]) {
                flag = false;
                break;
            }
        }
        if (flag) return true;
        return false;
    }
    bool go_check(int d, int x, int y) {    // 第奇数步必须走黑子,偶数步必须走白子
        if (d % 2) return maze[x][y] == 'B';
        else return maze[x][y] == 'W';
    }
    bool dfs(int d, int delta) {
        // test(d);
        if (d > D) return check();
        for (int x = 0; x < 4; x ++) {
            for (int y = 0; y < 4; y ++) {
                if (maze[x][y] == 'O') {
                    for (int i = 0; i < 4; i ++) {
                        int xx = x + dir[i][0], yy = y + dir[i][1];
                        if (in_map(xx, yy) && go_check(d+delta, xx, yy)) {
                            swap(maze[x][y], maze[xx][yy]);
                            if (dfs(d+1, delta)) return true;
                            swap(maze[x][y], maze[xx][yy]);
                        }
                    }
                }
            }
        }
        return false;
    }
    void handle() {
        for (D = 0; ; D ++) {
            // cout << "D = " << D << "..." << endl;
            if (dfs(1, 0) || dfs(1, 1)) break;
        }
    }
    int main() {
        for (int i = 0; i < 4; i ++) scanf("%s", maze[i]);
        handle();
        printf("%d
    ", D);
        return 0;
    }
    
  • 相关阅读:
    SQL注入漏洞
    回发或回调参数无效
    ListView绑定DataSet
    SQL注入漏洞全接触入门篇(二)
    条件运算符
    安全类
    ASP.NET常用代码集锦
    活动目录操作类
    x60系统安装步骤
    程序员是如何喝酒的
  • 原文地址:https://www.cnblogs.com/quanjun/p/13692950.html
Copyright © 2011-2022 走看看