Eight(bfs+全排列的哈希函数)
| Time Limit: 1000MS | Memory Limit: 65536K | |||
| Total Submissions: 22207 | Accepted: 9846 | Special Judge | ||
Description
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 x
where the only legal operation is to exchange 'x' with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle:
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8
9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12
13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x
r-> d-> r->
The letters in the previous row indicate which neighbor of the 'x' tile is swapped with the 'x' tile at each step; legal values are 'r','l','u' and 'd', for right, left, up, and down, respectively.
Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and
frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing 'x' tile, of course).
In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three
arrangement.
Input
1 2 3
x 4 6
7 5 8
is described by this list:
1 2 3 x 4 6 7 5 8
Output
Sample Input
2 3 4 1 5 x 7 6 8
Sample Output
ullddrurdllurdruldr 题意:这是一个8数码问题,听着好高端的样子;就是给你一个3*3的矩阵,包括1~8和x;例
1 2 3
x 4 6
7 5 8 问最少需要变换x几步成为 1 2 3
4 5 6
7 8 x 的形式; 这题的关键是找到一个哈希函数,使得矩阵形成的排列与一个自然数一一对应,这里采用的是全排列的哈希函数,另一个就是BFS加打印路径了;
#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
using namespace std; const int maxn = ;//根据全排列的哈希函数,n+1个数的排列可以对应n个数的多进制形式,这里九个数对应多进制的最大值为9!-1;
int factorial[] = {,,,,,,,,};
int pow[] = {,,,,,,,,};
int head,tail;
bool vis[maxn]; struct node
{
char status;
int id,num,pre;
}que[maxn]; int hash(int num)//全排列的哈希函数
{
int a[],key,i,j,c;
for(i = ; i < ; i++)
{
a[i] = num%;//a数组倒着存的num,所以求逆序数的时候条件是a[j]<a[i];
num = num/;
}
key = ;
for(i = ; i < ; i++)
{
for(j = ,c = ; j < i; j++)
{
if(a[j] < a[i])
c++;
}
key += c*factorial[i];
}
return key;
} void change(int num,int a,int b,char status)//a位置上的数和b位置上的数互换;
{
int n1,n2;
n1 = num/pow[a]%;
n2 = num/pow[b]%;
num = num - (n1-n2)*pow[a] + (n1-n2)*pow[b];
int key = hash(num);
if(!vis[key])
{
vis[key] = true;
que[tail].num = num;
que[tail].id = b;
que[tail].status = status;
que[tail++].pre = head;
}
} //打印路径
void print(int head)
{
char s[];
int c = ;
while(que[head].status != 'k')
{
s[c++] = que[head].status;
head = que[head].pre;
}
s[c] = '\0';
for(int i = c-; i >= ; i--)
{
printf("%c",s[i]);
}
printf("\n");
} int main()
{
char c;
int num,id,t; num = ;
for(int i = ; i < ; i++)
{
cin>>c;
if(c == 'x')
{
t = ;
id = i;
}
else t = c-'';
num = *num+t;
}
bool flag = false;
memset(vis,false,sizeof(vis)); head = ;
tail = ;
que[].id = id;
que[].num = num;
que[].status = 'k'; while(head < tail)
{
num = que[head].num;
id = que[head].id;
if(num == )
{
flag = true;
break;
}
if(id > )
change(num,id,id-,'u'); if(id < )
change(num,id,id+,'d'); if(id% != )
change(num,id,id-,'l');
if(id% != )
change(num,id,id+,'r');
head++; }
if(flag) print(head);
else printf("unsolvable\n");
return ;
}
Eight(bfs+全排列的哈希函数)的更多相关文章
- 字符串哈希函数(String Hash Functions)
哈希函数举例 http://www.cse.yorku.ca/~oz/hash.html Node.js使用的哈希函数 https://www.npmjs.org/package/string-has ...
- lintcode:哈希函数
题目: 哈希函数 在数据结构中,哈希函数是用来将一个字符串(或任何其他类型)转化为小于哈希表大小且大于等于零的整数.一个好的哈希函数可以尽可能少地产生冲突.一种广泛使用的哈希函数算法是使用数值33,假 ...
- 算法初级面试题05——哈希函数/表、生成多个哈希函数、哈希扩容、利用哈希分流找出大文件的重复内容、设计RandomPool结构、布隆过滤器、一致性哈希、并查集、岛问题
今天主要讨论:哈希函数.哈希表.布隆过滤器.一致性哈希.并查集的介绍和应用. 题目一 认识哈希函数和哈希表 1.输入无限大 2.输出有限的S集合 3.输入什么就输出什么 4.会发生哈希碰撞 5.会均匀 ...
- lintcode-->哈希函数
在数据结构中,哈希函数是用来将一个字符串(或任何其他类型)转化为小于哈希表大小且大于等于零的整数.一个好的哈希函数可以尽可能少地产生冲突.一种广泛使用的哈希函数算法是使用数值33,假设任何字符串都是基 ...
- php的哈希函数
哈希函数: echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n"; 验证函数: boolean ...
- 经常使用哈希函数的比較及其C语言实现
基本概念 所谓完美哈希函数.就是指没有冲突的哈希函数.即对随意的 key1 != key2 有h(key1) != h(key2). 设定义域为X,值域为Y, n=|X|,m=|Y|.那么肯定有m&g ...
- djb2:一个产生简单的随机分布的哈希函数
目录 LCG算法 示例代码 djb2 示例代码 为什么选择参数33和 33 was chosen because: 5381 was chosen because 哈希选择参考 LCG算法 djb2与 ...
- lintcode-128-哈希函数
128-哈希函数 在数据结构中,哈希函数是用来将一个字符串(或任何其他类型)转化为小于哈希表大小且大于等于零的整数.一个好的哈希函数可以尽可能少地产生冲突.一种广泛使用的哈希函数算法是使用数值33,假 ...
- Java集合(八)哈希表及哈希函数的实现方式
Java集合(八)哈希表及哈希函数的实现方式 一.哈希表 非哈希表的特点:关键字在表中的位置和它之间不存在一个确定的关系,查找的过程为给定值一次和各个关键字进行比较,查找的效率取决于和给定值进行比较的 ...
随机推荐
- Struts2 OGNL调用公共静态方法
在实现一个功能的时候用到了Struts2的OGNL 调用后台的静态方法,弄了半天没有出来结果,原来是自己没有在Struts的配置文件里面申明可以在前台使用后台的静态方法 <constant na ...
- int? 参数是这个的时候 是可以传入null的 而int的就不行
such as pager.CurrentPageIndex = (page != null ? (int)page : 1);
- AndroidManifest.xml中data标签中所有属性的含义
属性(ATTRIBUTES): android:host 这个属性用户定义URI授权的主机部分,除非给过滤器也指定了<data>元素的scheme属性,否则这个属性没有意义. 注意:在An ...
- 转: Oracle AWR 报告 每天自动生成并发送邮箱
原贴地址:http://www.cnblogs.com/vigarbuaa/archive/2012/09/05/2671794.html Oracle AWR 介绍http://blog.csdn. ...
- XCODE6 提交至 App Store
新到一个公司,以前的苹果开发人员离职,临时接手他的苹果代码,需要修改并上线到APP STORE. xcode6.0升级到最新的6.1后, 发现各种坑 1. 路径配置不对, 这个是个人习惯问题,之前的 ...
- C#操作数据库,将其查查出来的记录条数显示在winform窗体中的方法之一
//1.数据库链接的基本操作(略) //2.创建对象函数(关键部分) sqlConn.Open(); //初始化定义记录条数 ; object obj = sqlComm.ExecuteScalar( ...
- Java----多线程知识点归纳(概念)
一.线程与进程的区别: 多个进程的内部数据和状态都是完全独立的,而多线程是共享一块内存空间和一组系统资源,有可能互相影响. ?线程本身的数据通常只有寄存器数据,以及一个 程序执行时使用的堆栈,所以线程 ...
- sqlserver-事务处理
事务的概念:简单说就访问并可能更新数据库中各种数据项的一个程序执行单元,一旦开启事务,所有对数据的操作要么全部执行,要么全部都不执行.单条sql语句本身就是一个事务. 事务的属性: 事务是作为单个逻辑 ...
- golang bufio writer,reader 缓存规则
读,写,缓冲区可以杜绝频繁的读,写动作1.写缓存,如果一次write的长度大于buffer长度那么久发送当前缓冲区的内容并且发送要写入的内容,就是不在缓存了.如果发送的内容小于buffer长度,就按缓 ...
- php开发利器
phpstorm 当前版本2016.1 之前用的为Zend studio,比之notepad++确实方便很多,不过很多方面还是不方便的,比如定位文件,上传下载到svn什么的. 看到phpstorm新版 ...