八数码难题

——!x^n+y^n=z^n

  我在此只说明此题的一种用BFS的方法,因为本人也是初学,勉勉强强写了一个单向的BFS,据说最快的是IDA*(然而蒟蒻我不会…)

  各位如果想用IDA*的可以看看这位大佬的这篇文章:

http://www.cnblogs.com/ZYBGMZL/p/6852733.html

  接下来是我的方法,用luogu的跑了最慢是200ms,感觉还行把。

题目描述

在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。

输入输出格式

输入格式:

输入初试状态,一行九个数字,空格用0表示

输出格式:

只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)

输入输出样例

输入样例#1

283104765

输出样例#1

4

  因为这是要最优解且保证数据有解,于是就想到了BFS。

  然而这个过程是有许多障碍的,要怎样检验自己的状态是否为解,还有判重的操作,如果你没有判重,TLE即在眼前…

所以我们可以想到压缩状态!当然如果用二进制难免有点力不从心,那我们干脆存成整数不就行了?但是可能你会发现,会有前导零的情况,怎么办?

这时候其实可以在状态前加一个1,在int型中还是过得去的。

  那判重怎么搞?注意到这只有9!种状态。

  想到什么?康托尔展开!对于0~8的全排列,

  012345678 的字典序是1,如果让你手动操作我想没什么问题,那怎么让计算机做这件事?

  对于 (a(n-1) a(n-2)L a(0))的字典序计算方法为:

  Σ(ci*i!)ci为当前未出现的比ai小的数的个数。

  既然这样,我们就能把状态一一存下来了,交换的话很简单,读者手动操作即可发现规律。

  简单说明之后附上代码参考一下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 400000
//阶乘?我当然打表啦。
]={,,,,,,,,,};
//状态
struct sjs{
    int num;
    int pos;
}state[maxn];
//队列
struct _757{
    int time;
    int now;
    int fd;
}qu[maxn];
];
//判重
bool rep[maxn];
int head,tail;
//特殊嗜好???
namespace lys{
    //快速幂
    int fpow(int p){
        ,;
        ){
            ) res*=base;
            base*=base;
            p>>=;
        }
        return res;
    }
    //计算cantor
    int cantor(int num){
        ,pos,res=;
        int x=num;
        memset(cto,,sizeof cto);
        ){
            cto[i]=num%;
            ) pos=i;
            num/=;
            i++;
        }
        int j,cal;
        ;i>=;i--){
            cal=;
            ;j>i;j--){
                if(cto[j]<cto[i]) cal++;
            }
            res+=(cto[i]-cal)*fac[i];
        }
        state[res+].num=x;
        state[res+].pos=pos;
        ;
    }
    //判断是否能移动
    bool chk(int pos,int i){
        switch(i){
            :) return true ; return false ;
            :) return true ; return false ;
            :||pos==||pos==) return false ; return true ;
            :||pos==||pos==) return false ; return true ;
        }
    }
    int bfs(){
        ,i,st,ch,fp,x,num;
        do{
            st=qu[head].now;
            fp=fpow(state[st].pos);
            num=state[st].num;
            ;i<=;i++){
                if(chk(state[st].pos,i)){
                    switch(i){
                        :
                            x=(num/(fp*))%;
                            ch=num-x*fp*+x*fp;
                            x=cantor(ch);
                            qu[++tail].now=x;
                            qu[tail].time=(qu[head].time+);
                            qu[tail].fd=head;
                            //目标态,觉得不这样写也行,直接用num比较
                            ){
                                return qu[tail].time;
                            }
                            if(rep[x]) tail--;
                            else rep[x]=true ;
                            break ;
                        :
                            x=(num/(fp/))%;
                            ch=num-x*fp/+x*fp;
                            x=cantor(ch);
                            qu[++tail].now=x;
                            qu[tail].time=(qu[head].time+);
                            qu[tail].fd=head;
                            ){
                                return qu[tail].time;
                            }
                            if(rep[x]) tail--;
                            else rep[x]=true ;
                            break ;
                        :
                            x=(num/(fp*))%;
                            ch=num+x*fp-x*fp*;
                            x=cantor(ch);
                            qu[++tail].now=x;
                            qu[tail].time=(qu[head].time+);
                            qu[tail].fd=head;
                            ){
                                return qu[tail].time;
                            }
                            if(rep[x]) tail--;
                            else rep[x]=true ;
                            break ;
                        :
                            x=(num/(fp/))%;
                            ch=num+x*fp-x*fp/;
                            x=cantor(ch);
                            qu[++tail].now=x;
                            qu[tail].time=(qu[head].time+);
                            qu[tail].fd=head;
                            ){
                                return qu[tail].time;
                            }
                            if(rep[x]) tail--;
                            else rep[x]=true ;
                            break ;
                    }
                }
            }
            head++;
        }while(head<=tail);
    }
    int main(){
        int i,j;
        char c;
        ;
        ;i<=;i++){
            ;j<=;j++){
                c=getchar();
                ') c=getchar();
                st=st*+c-';
            }
        }
        //初始状态
        +st);
        qu[++head].now=r;
        qu[head].time=;
        rep[r]=true ;
        tail=;
        printf("%d\n",bfs());
        ;
    }
}
int main(){
    lys::main();
    ;
}

[luogu]P1379 八数码难题[广度优先搜索]的更多相关文章

  1. luogu P1379 八数码难题

    题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了 ...

  2. luogu P1379 八数码难题(A*算法入门详细讲解)

     代码实现细节 #include<cstdio> #include<cstring> #include<iostream> using namespace std; ...

  3. 洛谷 P1379 八数码难题 解题报告

    P1379 八数码难题 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初 ...

  4. 洛谷——P1379 八数码难题

    P1379 八数码难题 双向BFS 原来双向BFS是这样的:终止状态与起始状态同时入队,进行搜索,只不过状态标记不一样而已,本题状态使用map来存储 #include<iostream> ...

  5. 洛谷P1379八数码难题

    题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中. 要求解的问题是:给出一种初始布局(初始状态)和目标布局(为 ...

  6. codevs1225八数码难题(搜索·)

    1225 八数码难题  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description Yours和zero在研究A*启 ...

  7. 洛谷—— P1379 八数码难题

    https://daniu.luogu.org/problem/show?pid=1379 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示 ...

  8. 洛谷 P1379 八数码难题

    题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了 ...

  9. 洛谷 - P1379 - 八数码难题 - bfs

    https://www.luogu.org/problemnew/show/P1379 #include <bits/stdc++.h> using namespace std; #def ...

随机推荐

  1. oracle 体系结构简介

    1.1.SGA(system global area) SGA是oracle Instance的基本组成部分,在示例启动是分配.是一组包含一个oracle实例的数据和控制信息的共享内存结构.主要用于存 ...

  2. Chapter 7:Statistical-Model-Based Methods

    作者:桂. 时间:2017-05-25  10:14:21 主要是<Speech enhancement: theory and practice>的读书笔记,全部内容可以点击这里. 书中 ...

  3. Java基础——抽象类和接口

    之所以将抽象类和接口放在一起做笔记,是因为他们之间很难区分又各自独立.在学习完Java程序设计的三大特点(封装.继承.多态)之后,我最大的收获是,慢慢理解了Java语言这种面向对象程序设计的优越性,它 ...

  4. Bash Shell编程要点小结

    一.case命令 case variable invalue1) command(s);; value2) command(s);; *) command(s);; esac 如果case变量没有被匹 ...

  5. 一个比较完善的httpWebRequest 封装,适合网络爬取及暴力破解

    大家在模拟http请求的时候,对保持长连接及cookies,http头部信息等了解的不是那么深入.在各种网络请求过程中,发送N种问题. 可能问题如下: 1)登录成功后session保持 2)保证所有c ...

  6. 关于MATLAB处理大数据坐标文件2017622

    今天新提交了一次数据,总量达到10337个,本以为成绩会突飞猛进,没想到还是不如从前 但是已经找到人工鼠标轨迹的程序,有待完善,接下来兵分四路:找特征.决策树.完善人工轨迹程序,使其可以将生成的数据自 ...

  7. SSH连接不上CentOS 主机配置文件导致的原因的解决方法

    一.CentOS之SSH的安装与配置 SSH 为 Secure Shell 的缩写,由 IETF 的网络工作小组(Network Working Group)所制定SSH 为建立在应用层和传输层基础上 ...

  8. 详解ES6中的 let 和const

      前  言 JRedu ECMAScript 6 是 JavaScript 语言教程,全面介绍 ECMAScript 6 新引入的语法特性. ES6 与上一个版本 ES5 的所有不同之处,对涉及的语 ...

  9. 【Android Developers Training】 6. 配置Action Bar

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  10. java对mysql的增删改查

    -----连接数据库 package connectdb;import java.sql.*;class Dbcon { // 此处连接数据库,独立开一个类,以后操作数据库的每次连接就不用写这么多 p ...