• Poj 1166 The Clocks(bfs)


    题目链接:http://poj.org/problem?id=1166

    思路分析:题目要求求出一个最短的操作序列来使所有的clock为0,所以使用bfs;

    <1>被搜索结点的父子关系的组织:

    在bfs中,队列中存储着解答树中搜索过的结点,并且每个结点都可以使用它在队列中的位置作为其唯一的ID;

    另外,使用另一个数组存储结点的父节点和从父节点到该节点的操作,同样的,使用结点在队列中的位置作为该节点的ID;

    这种方法类似于并查集的方法,使用多个线性数组来模拟树的结构;这里模拟解答树中搜索过的结点构成的树的结构;

    <2>判重方法: 对于每个结点都有一个唯一的状态,使用位运算进行状态压缩和一个判重数组即可实现判重;

    代码如下:

    #include <queue>
    #include <vector>
    #include <iostream>
    using namespace std;
    
    const int mod = 0333333333; // 以0开头的数字代表八进制
    const int MAX_N = (1 << 18) + 10;
    int clock[9];
    bool vis[mod];
    int fa[MAX_N], path[MAX_N], state_queue[MAX_N], ans[MAX_N];
    char mov[9][6] = {"ABDE", "ABC", "BCEF", "ADG", "BDEFH", "CFI", "DEGH", "GHI", "EFHI"};
    
    int Bfs(int s)
    {
        int start, head, tail;
    
        start = s;
        head = tail = 0;
        state_queue[tail++] = start;
        fa[0] = -1;
        vis[start] = true;
    
        while (head < tail)
        {
            int now = state_queue[head];
    
            for (int i = 0; i < 9; ++i)
            {
                int k = 0, value;
                int next = now;
    
                while (mov[i][k] != NULL)
                {
                    value = mov[i][k] - 'A';
                    next = next + (1 << (3 * value));
                    next = next & mod;
                    k++;
                }
    
                if (!vis[next])
                {
                    fa[tail] = head;
                    path[tail] = i + 1;
    
                    if (next == 0)
                        return tail;
                    else
                    {
                        vis[next] = true;
                        state_queue[tail++] = next;
                    }
                }
            }
            head++;
        }
        return -1;
    }
    
    void PrintPath(int k)
    {
        int end = k, start = end;
        int len = 0;
    
        while (fa[start] != -1)
        {
            ans[len++] = path[start];
            start = fa[start];
        }
    
        for (int i = len - 1; i > 0; --i)
            printf("%d ", ans[i]);
        printf("%d
    ", ans[0]);
    }
    
    int main()
    {
        int start, ans, temp = 0;
    
        start = 0;
        for (int i = 0; i < 9; ++i)
        {
            scanf("%d", &temp);
            start += temp << (3 * i);
        }
        
        ans = Bfs(start);   
        PrintPath(ans);
        return 0;
    }
  • 相关阅读:
    思考题13-1.b
    算法导论 第三版 9.3-8
    算法导论第三版思考题8-4
    算法导论第三版思考题8-3.b
    算法导论第三版思考题8-3.a
    算法导论第三版思考题8-2.e
    算法导论 第三版 思考题 7-4
    test
    一个朋友面试时遇到的算法题(怎么组合后得到最大整数)
    监听器模式、观察者模式
  • 原文地址:https://www.cnblogs.com/tallisHe/p/4507459.html
Copyright © 2020-2023  润新知