zoukankan      html  css  js  c++  java
  • graph-bfs-八数码问题

    这个看起来是童年回忆:)

    大体思路是,将每个排列状态看成图中的一个点,状态之间转换说明有边。然后用bfs,如果遍历完之后还是没有找到目标状态,

    则说明是无解的,否则输出步数。具体想法写在代码里吧,多多理解。

    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    #include <string.h>
    #include <cmath>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    const int N = 1000000, HN = 1000003;
    // linked list for hash table.
    int head[HN], next[N];
    int state[N][9], goal[9];
    // # steps
    int dist[N];
    const int dx[4] = {-1, 1, 0, 0};
    const int dy[4] = {0, 0, -1, 1};
    
    // map into a number of 9 digits
    int hash(int *arr) {
        int v = 0;
        for (int i = 0; i < 9; i++) {
            v = v * 10 + arr[i];
            }
        // make sure not overflow
        return v % HN;
        }
    // insert a state
    bool tryInsert(int rear) {
        int h = hash(state[rear]);
        int u = head[h];
        while (u) {
            // if repeated
            if (!memcmp(state[u], state[rear], sizeof(state[0])))
                return false;
            u = next[u];
            }
            // insert rear to the front
            next[rear] = head[h];
            head[h] = rear;
            return true;
        }
    int bfs() {
        // initiate head
        memset(head, 0, sizeof(head));
        //memset(dist, 0, sizeof(dist));
        int front = 1;
        int rear = 2;
        while (front < rear) {
            // same, memcmp return 0
            // means find goal
            if (!memcmp(goal, state[front], sizeof(state[0])))
                return front;
            int z;
            // find 0
            for (z = 0 ; z < 9; z++)
                if (!state[front][z])
                    break;
            int x = z / 3;
            int y = z % 3;
            for (int d = 0; d < 4; d++) {
                int nx = x + dx[d];
                int ny = y + dy[d];
                int nz = 3 * nx + ny;
                // judge if still in 
                if (nx >= 0 && nx < 3 && ny >= 0 && ny < 3) {
                    memcpy(&state[rear], &state[front], sizeof(state[0]));
                    // move
                    state[rear][nz] = state[front][z];
                    state[rear][z] = state[front][nz];
                    dist[rear] = dist[front] + 1;
                    if (tryInsert(rear))
                        rear ++;
                    }
                }
                // front pop
                front ++;
            }
        return 0;
        }
    int main() {
        //freopen("hhInput.in", "r", stdin);
        for (int i = 0; i < 9; i++)
            // 1 3 0 8 2 4 7 6 5
            cin >> state[1][i];
        for (int i = 0; i < 9; i++)
            // 1 2 3 8 0 4 7 6 5
            cin >> goal[i];
        int ans = bfs();
        if (ans > 0) 
            cout << dist[ans] << endl;
        else
            cout << "-1" << endl;
        return 0;
        }
    

      

  • 相关阅读:
    mysql 设置无密码登陆
    phpstudy mysql 升级5.7.18
    php 统计二维数组中某个相等值的总个数,并且组合成一个新的数组 转发
    centos 安装 composer
    PHP不定维数组去除空值
    jQuery中$.ajax()详解(转)
    JSON详解(转发自博客园)
    详解CMS垃圾回收机制
    内存管理
    什么是同源策略
  • 原文地址:https://www.cnblogs.com/pxy7896/p/6622848.html
Copyright © 2011-2022 走看看