紫书p199 八连块(BFS,hash)

八连块问题  紫书上的简单搜索  渣渣好久才弄懂

#include<cstdio>
#include<cstring>
using namespace std;
const int M = 1000003;
int x[4] = { -1, 1, 0, 0}, y[4] = {0, 0, -1, 1};
int dis[M], h[M], s[M][9], e[9];

int aton(int a[])
{
    int t = 0;
    for(int i = 0; i < 9; ++i)
        t = t * 10 + a[i];
    return t;
}

int search_hash(int a[])
{
    int t = aton(a), p = t % M;
    while(h[p])
    {
        if(h[p] == t) return p;
        ++p;
        if(p >= M) p = 0;
    }
    return p;
}

int bfs()
{
    memset(h, 0, sizeof(h));
    int fro = 1, rear = 2, r, c, k = 0, p;
    int t[9], tmp, cur, nr, nc, nk;

    while(fro < rear)
    {
        memcpy(t, s[fro], sizeof(t));
        cur = search_hash(t);
        if(memcmp(t, e, sizeof(t)) == 0) return dis[cur];
        for(k = 0; t[k];) ++k;
        r = k / 3, c = k % 3;
        for(int i = 0; i < 4; ++i)
        {
            memcpy(t, s[fro], sizeof(t));
            nr = r + x[i], nc = c + y[i], nk = nr * 3 + nc;
            if(nr < 0 || nr > 2 || nc < 0 || nc > 2) continue;
            tmp = t[nk];
            t[nk] = 0;
            t[k] = tmp;
            p = search_hash(t);
            if(h[p] == 0)
            {
                h[p] = aton(t);
                dis[p] = dis[cur] + 1;
                memcpy(s[rear], t, sizeof(t));
                ++rear;
            }
        }
        ++fro;
    }
    return -1;
}

int main()
{
    while(~scanf("%d", &s[1][0]))
    {
        memset(dis, 0, sizeof(dis));
        for(int i = 1; i < 9; ++i)
            scanf("%d", &s[1][i]);
        for(int i = 0; i < 9; ++i)
            scanf("%d", &e[i]);
        h[aton(s[1]) % M] = aton(s[1]);
        int ans = bfs();
        if(ans != -1)
            printf("%d\n", ans);
        else  printf("No solution\n");
    }
    return 0;
}
/*
2 6 4 1 3 7 0 5 8
8 1 5 7 3 6 4 0 2
2 3 4 1 5 0 7 6 8
1 2 3 4 5 6 7 8 0
*/
时间: 2024-10-11 00:41:57

紫书p199 八连块(BFS,hash)的相关文章

HDU 1043 Eight八数码解题思路(bfs+hash 打表 IDA* 等)

题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原为初始状态 思路: 参加网站比赛时拿到此题目,因为之前写过八数码问题,心中暗喜,于是写出一套暴力bfs+hash,结果TLE呵呵 思路一:bfs+hash(TLE) 1 #include <cstdio> 2 #include <cstring> 3 #include <queu

紫书第4章 函数和递归

1  序 系统的整理下第四章的学习笔记.同上次一样,尽量在不依赖书本的情况下自己先把例题做出来.这次有许多道题代码量都比较大,在例题中我都用纯C语言编写,但由于习题的挑战性和复杂度,我最终还是决定在第五章开始前,就用C++来完成习题.不过所有的代码都是能在C++提交下AC的. 在习题中,我都习惯性的构造一个类来求解问题,从我个人角度讲,这会让我的思路清晰不少,希望自己的一些代码风格不会影响读者对解题思路的理解. 其实在第四章前,我就顾虑着是不是真的打算把题目全做了,这些题目代码量这么大,要耗费很

第11章例题(紫书)

10/15 这几天先专心刷一下图论的基础题目,也蛮多的,慢慢来... 例题11-1 uva 12219 题意:给你一个表达式,然后又一些子树在之前重复出现过,先要你给这些子树出现的顺序编个号1...N,然后如果重复出现就用编号替代,输出替代之后的表达式. 题解:这是一个表达式树的问题,显示建树,如果让我来写的话,很麻烦,搞不好复杂度是O(n^2),因为字符串是一直扫描下去的,所以就利用一个指针作为全局,然后一直扫下去,就忽略一个左括号,建左树,然后忽略逗号,建右树,忽略右括号,然后一直扫下去,就

第10章例题(紫书)

21/21 题目都很基础,有很多题书上讲得比较详细,然后隔得时间有点久,所以具体什么trick都忘了,思路也懒得去回忆,所以将就着放上来了.... 例题10–1 Uva 11582 题意:输入a, b, n让你计算F[a^b]%n;其中这个F[i]是斐波那契数: 题解: 这题是快速幂+找循环节,用什么方法找循环节呢?因为第一个数是0和1,然后当再出现0和1的时候就是出现循环节的时候,然后假如找到了循环节T,然后就有F[n] = F[n % T],预处理找循环节,O(一百万左右),快速幂logn

紫书p155 用中序后序构造二叉树

二叉树各节点权值是不相同的正整数,输入二叉树的中序后序,求到根节点权和最小的叶节点 紫书贼强,递归写的服气,慢慢理解吧 原文是建树之后用dfs搜的,我试着一边建树一边归纳最短路径 #include<bits/stdc++.h> using namespace std; const int maxv = 10010; int in[maxv], post[maxv], lch[maxv], rch[maxv];//中序,后序,左子树,右子树 int n, minnum, minsum; bool

紫书第三章 数组和字符串

1  序 系统的整理下第三章的学习笔记.例题代码是在未看书本方法前自己尝试并AC的代码,不一定比书上的标程好:习题除了3-8百度了求解方法,其它均独立完成后,会适当查阅网上资料进行整理总结.希望本博文方便自己日后复习的同时,也能给他人带来点有益的帮助(建议配合紫书--<算法竞赛入门经典(第2版)>阅读本博客).有不足或错误之处,欢迎读者指出. 2  例题 2.1  UVa272--Tex Quotes #include <stdio.h> int main() { bool log

CNUOJ 0079 20612统计八连块

20612统计八连块 难度级别:B: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 输入一个m行n列的字符矩阵,统计字符“@”组成多少个八连块.如果两个字符“@”所在的格子相邻(横竖或者对角线方向),就说它们属于同一个八连块.例如,下图中有两个八连块.                         输入 第一行包括两个正整数m和n,由空格隔开,接下来的m行,每行n个字符,字符只包括“*”和“@”. 输出 一个自然数,表示八连块的个数.

20612统计八连块

50237242海岛帝国:神圣之日 [试题描述] 输入一个m行n列的字符矩阵,统计字符“@”组成多少个八连块.如果两个字符“@”所在的格子相邻(横竖或者对角线方向),就说它们属于同一个八连块.例如,下图中有两个八连块. [输入要求] 第一行包括两个正整数m和n,由空格隔开,接下来的m行,每行n个字符,字符只包括“*”和“@”. [输出要求] 一个数,表示八连块的个数 [输入实例] 5 5 ****@ *@@*@ *@**@ @@@*@ @@**@ [输出实例] 2 [其他说明] 数据范围:0<m

UAa 1339,紫书P73,词频

题目链接:https://uva.onlinejudge.org/external/13/1339.pdf 紫书P73 解题报告: #include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> using namespace std; int main() { //freopen("input.txt","r",stdin