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集合(八)哈希表及哈希函数的实现方式 一.哈希表 非哈希表的特点:关键字在表中的位置和它之间不存在一个确定的关系,查找的过程为给定值一次和各个关键字进行比较,查找的效率取决于和给定值进行比较的 ...
 
随机推荐
- 自定义控件(视图)2期笔记10:自定义视图之View事件分发机制("瀑布流"的案例)
			
1. Touch事件的传递: 图解Touch事件的传递,如下: 当我们点击子View 02内部的Button控件时候,我们就触发了Touch事件. • 这个Touch事件首先传递给了顶级父View ...
 - MySQL存储过程学习笔记
			
MySQL在5.0以前并不支持存储过程,这使得MySQL在应用上大打折扣.MySQL 5.0终于开始支持存储过程了. MySQL的关键字大小写通用.该学习笔记对关键字使用大写:变量名,表名使用小写. ...
 - 关于Entity Framework 5 从数据库生成模型时没有字段注释的解决方法!
			
目前用到了EF5进行模型创建,发现从数据库生成过来的实体中并没有包含字段的说明信息(鄙视下微软,这么简单的问题都不给解决下,太粗枝大叶了),网上找到了EFTSQLDocumentation.Gener ...
 - Java-Hirbernate小结大纲
			
Hibernate Hibernate是一个开放源代码的对象关系映射框架 Hibernate的核心接口一共有6个,分别为:Session.SessionFactory.Transaction.Quer ...
 - 如何在获取Datarow对象在其所属DataTable中的Index
			
做项目的时候需要先select一个DataTable的子集,后来又需要子集中这些DataRow的Index, 这个需求本来就有些奇怪,网上也没搜到.刚开始走了很多弯路,后来发现一个简便方法 'dr是你 ...
 - SDK Manager.exe 无法启动,一闪而过的解决办法
			
删掉 C:\Windows\system32\ 下的 java.exe.javaw.exe.javaws.exe 即可解决.(转载)
 - Java排序8大算法实现
			
概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大, ...
 - C# - string 转为 DateTime(自定义)
			
上代码: string dt = " 1 11 1961"; DateTime day; System.Globalization.DateTimeFormatInfo dtFor ...
 - 【POJ1733】【带标记并查集】Parity game
			
Description Now and then you play the following game with your friend. Your friend writes down a seq ...
 - AppiumDriver 运行app启动基本参数
			
记录一下 DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability(Mobile ...