洛谷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\n", D);
    return 0;
}
posted @ 2020-09-18 18:54  quanjun  阅读(348)  评论(0编辑  收藏  举报