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\n", 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;
}
时间: 2024-10-12 13:23:07

Poj 1166 The Clocks(bfs)的相关文章

POJ 1166 The Clocks (爆搜 || 高斯消元)

题目链接 题意: 输入提供9个钟表的位置(钟表的位置只能是0点.3点.6点.9点,分别用0.1.2.3)表示.而题目又提供了9的步骤表示可以用来调正钟的位置,例如1 ABDE表示此步可以在第一.二.四.五个钟调正,如原来是0点,那么调正后为3点.问经过那些步骤可以导致9个钟的位置都在0点. 分析: 这个本来是一个高斯消元的题目,但是 听说周期4不是素数, 求解过程中不能进行取余.因为取余可能导致解集变大. 不过也有用高斯消元做的,下面是用高斯消元的分析 ” Discuss也有人讨论了,4不是质数

POJ 1166 The Clocks 高斯消元 + exgcd(纯属瞎搞)

根据题意可构造出方程组,方程组的每个方程格式均为:C1*x1 + C2*x2 + ...... + C9*x9 = sum + 4*ki; 高斯消元构造上三角矩阵,以最后一个一行为例: C*x9 = sum + 4*k,exgcd求出符合范围的x9,其他方程在代入已知的变量后格式亦如此. 第一发Gauss,蛮激动的. #include <algorithm> #include <iostream> #include <cstring> #include <cstd

poj 1166 The Clocks 记录路径的广搜

题意: 给9个时钟的初始状态,和一些对某几个钟的操作,求最少经过几步能到目标状态(全指向12点). 分析: 明显的广搜,但实现起来的细节要注意:1.因为要记录路径,所以要在整个程序执行过程中扩展出的节点在输出路径前不能销毁, 故采用静态内存分配的方法(开node[600000],用get_node()创建节点.2.queue<node>比queue<int>要多花1别的时间. //poj 1166 //sep9 #include <iostream> #include

POJ 1166 The Clocks 位运算与BFS

1.题意:有一组3*3的只有时针的挂钟阵列,每个时钟只有0,3,6,9三种状态:对时针阵列有9种操作,每种操作只对特点的几个时钟拨一次针,即将时针顺时针波动90度,现在试求从初试状态到阵列全部指向0的状态所需要的最小操作数的操作方案: 2.输入输出:输入给出阵列初始状态,0,1,2,3分别表示0,3,6,9:要求输出最快方案的操作序列: 3.分析:IOI 1994的考题,BFS是比较容易想到的方法之一,关键是如何简洁的表示和改变BFS过程中的阵列状态:这里使用位运算的方法:具体如下: 首先一共9

poj 1166 The Clocks (暴搜)

The Clocks Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15944   Accepted: 6493 Description |-------| |-------| |-------| | | | | | | | |---O | |---O | | O | | | | | | | |-------| |-------| |-------| A B C |-------| |-------| |-------|

POJ 1166 The Clocks

高斯消元法第四个冠军,这个称号是非常令人兴奋~~ 题目大意: 给出9个钟表的状态.给出九种操作,问最少要操作几次能把全部的钟表调回12点. 解题思路: 对于9个钟表分别列方程,然后高斯消元就可以.因为这次左边的方程系数不是0就是1,所以不用找最大值~ 以下是代码: #include <set> #include <map> #include <queue> #include <math.h> #include <vector> #include

Dearboy&#39;s Puzzle (poj 2308 搜索 dfs+bfs)

Language: Default Dearboy's Puzzle Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1202   Accepted: 208 Description Dearboy is a game lover. Recently, he loves playing the game Lian Lian Kan. This game is played on a board with N*M grids

poj 3026 Borg Maze (bfs + 最小生成树)

链接:poj 3026 题意:y行x列的迷宫中,#代表阻隔墙(不可走),空格代表空位(可走),S代表搜索起点(可走) A代表外星人站(可走),现在要从S出发,将S和所有的A之间都连通,求路线总距离最小值 分析:可以先用bfs将所有的A,S两两之间的最短距离,题目的目的是将S与所有的A连通,使得总距离最小, 所有任选一点开始按最小生成树的算法做就行,并非非要从S点开始 注:题目输入x,y后可能有很多空格,可以用gets将多余的空格取走,开数组是尽量开大点,之前虽然开的比题目数据     稍大,但一

POJ 2329 (暴力+搜索bfs)

Nearest number - 2 Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3943 Accepted: 1210 Description Input is the matrix A of N by N non-negative integers. A distance between two elements Aij and Apq is defined as |i ? p| + |j ? q|. Your pro