VIjos 晴天小猪历险记之Number (搜索+链表hash)

背景

话说上一回,晴天小猪不畏千难万险、千辛万苦、千磨万难……终于爬上了那座深山,来到了那位隐者的小屋中,但它不知道,有一个问题正等待着它……
晴天小猪一推开门,就发现那里……空无一人?但在屋中央有一个石桌,上面有一些字(强吧),最大的几个:如要见我,先过了这道关再说!
晴天小猪定睛一看,终于发现桌上密密麻麻布满了字,费了九天二猪之力,终于将题目看完,大意是:为了维护世界的和平……我们需要让九位勇士组成一个3*3的阵型去屠龙,但是这个阵型的要求很奇特,要九个人按照强弱依次编号1~9,且阵型中每行、每列、每条长对角线上的数字和都为15,这样才能使龙对勇士和阵型收到的损害最小,但九位勇士光是争夺名次就开始翻脸,各位**(任君想象)忙得不可开交,但晴天小猪也急得不可开交(-_-|||),只好向你求助。

描述

现在假设九位勇士已编好了号(感觉好像有人盯着我……)并站好了位置,例如:
7 8 9
1 2 3
4 5 6
每一次交换都可以将相邻的两位勇士(也就是编号……)交换位置,例如:
7 9 8
1 2 3 (8与9交换)
4 5 6

7 8 9
4 2 3 (4与1交换)
1 5 6
但不能
7 8 9
5 2 3 (1与5交换)
4 1 6
求最少的交换次数,使得九位勇士能在最短的时间内(当然是他们争完后……)以最安全的阵型去屠龙。

P.S:由于不能预测未来,各位设想了许多的阵型(-_-||),所以给了你10组阵型(测试点),每组50个……

格式

输入格式

输入数据一共3*50行,每个数据中用3*3的9个不同的1~9的数字表示初始状态。

(样例就只给几个阵型了^_^)

输出格式

每行一个数,即对应的初始阵型到所需阵型所需最少的交换次数,如果无解,输出-1。

样例1

样例输入1

7 8 9
1 2 3
4 5 6
6 1 8
7 5 3
2 9 4
1 2 8
3 5 4
6 7 9

Copy

样例输出1

8
0
5

Copy

限制

各个测试点5s

提示

欲知后事如何,请做出此题^_^。

来源

Sunnypig

  1 /*
  2     链表hash
  3     应该都能懂
  4     我们的目标序列有八个
  5     把这个矩阵按顺序展开之后
  6     其实就是一个1-9的全排列
  7     直接将八个目标状态丢进队列中
  8     让他扩展完将所有情况的最小距离的找出来
  9     只要手写一个数组模拟链表hash就好了
 10 */
 11 #include<queue>
 12 #include<cstdio>
 13 #include<iostream>
 14 #define MAXN 100010
 15 #define MOD 30000007
 16
 17 using namespace std;
 18
 19 int a[3][3];
 20
 21 struct node {
 22     int to;
 23     int step;
 24     int next;
 25 };
 26 node e[MOD];
 27
 28 int head[MOD],tot;
 29
 30 int step=-1;
 31
 32 queue<node> q;
 33
 34 inline void hash_make(int x) {
 35     int k=x%MOD;
 36     e[++tot].to=x;
 37     e[tot].step=step+1;
 38     e[tot].next=head[k];
 39     head[k]=tot;
 40     q.push(e[tot]);
 41 }
 42
 43 inline void init() {
 44     q.push((node){816357492,0,-1});q.push((node){438951276,0,-1});
 45     q.push((node){294753618,0,-1});q.push((node){672159834,0,-1});
 46     q.push((node){618753294,0,-1});q.push((node){276951438,0,-1});
 47     q.push((node){492357816,0,-1});q.push((node){834159672,0,-1});
 48     fill(head,head+MOD+1,-1);
 49     hash_make(816357492);hash_make(294753618);hash_make(618753294);hash_make(492357816);
 50     hash_make(438951276);hash_make(672159834);hash_make(276951438);hash_make(834159672);
 51 }
 52
 53 inline void translation(int x) {
 54     for(int i=2;i>=0;i--)
 55       for(int j=2;j>=0;j--) {
 56           a[i][j]=x%10;
 57           x/=10;
 58       }
 59     return;
 60 }
 61
 62 inline int digit() {
 63     int ans=0;
 64     for(int i=0;i<3;i++)
 65       for(int j=0;j<3;j++) {
 66           ans=ans*10+a[i][j];
 67       }
 68     return ans;
 69 }
 70
 71 inline int hash_find(int x) {
 72     int k=x%MOD;
 73     for(int i=head[k];i!=-1;i=e[i].next)
 74         if(e[i].to==x) return e[i].step;
 75     return -1;
 76 }
 77
 78 inline void move(int x,int y,int xx,int yy) {
 79     swap(a[x][y],a[xx][yy]);
 80     int t=digit();
 81     if(hash_find(t)==-1)
 82       hash_make(t);
 83     swap(a[x][y],a[xx][yy]);
 84 }
 85
 86 inline void bfs() {
 87     while(!q.empty()) {
 88         node p=q.front();
 89         q.pop();
 90         translation(p.to);
 91         step=p.step;
 92         for(int i=0;i<3;i++)
 93           for(int j=0;j<3;j++) {
 94               if(i!=2) move(i,j,i+1,j);
 95               if(j!=2) move(i,j,i,j+1);
 96           }
 97     }
 98 }
 99
100 inline void _printf() {
101     int ans=0,x;
102     while(scanf("%d",&ans)!=EOF) {
103         for(int i=1;i<=8;i++) {
104             scanf("%d",&x);
105             ans=ans*10+x;
106         }
107         printf("%d\n",hash_find(ans));
108     }
109     return;
110 }
111
112 int main() {
113     init();
114     bfs();
115     _printf();
116     return 0;
117 }

代码

时间: 2024-08-11 07:35:13

VIjos 晴天小猪历险记之Number (搜索+链表hash)的相关文章

HDU 4937 Lucky Number 搜索

题意: 给你一个数,求在多少种不同的进制下这个数每一位都是3.4.5.6中的一个. 思路: 搜索.枚举这个数在任意进制下的表示,判断是否合法.当数字只有3.4.5.6时,必定有无穷种. 因为数字太大,所以直接枚举必定会超时. 下面有两种剪枝的方法: 1. 先枚举最后一位的情况. 假设数字n在base进制下表示为 a[n]...a[0],即 n = a[0] + a[1]*base^1 + ... + a[n]*base^n. 则 n - a[0] = a[1]*base^1 + ... + a[

Mine Number(搜索,暴力) ACM省赛第三届 G

1 安装及下载client 端 2 什么是SVN(Subversion)? 3 为甚么要用SVN? 4 怎么样在Windows下面建立SVN Repository? 5 建立一个Working目录 6 新增档案及目录到Repository中 7 更新档案及目录 8 更新至特定版本 9 复制档案及目录 10 制作Tag或是Release 11 快速参考 11.1 取得(Checkout)Repository 11.2 更新(Update)档案或目录 11.3 新增(Add)档案或目录 11.4 提

回档|晴天小猪历险记之hill

背景 Background 在很久很久以前,有一个动物村庄,那里是猪的乐园(^_^),村民们勤劳.勇敢.善良.团结…… 不过有一天,最小的小小猪生病了,而这种病是极其罕见的,因此大家都没有储存这种药物.所以晴天小猪自告奋勇,要去采取这种药草.于是,晴天小猪的传奇故事便由此展开…… 描述 Description 这一天,他来到了一座深山的山脚下,因为只有这座深山中的一位隐者才知道这种药草的所在.但是上山的路错综复杂,由于小小猪的病情,晴天小猪想找一条需时最少的路到达山顶,但现在它一头雾水,所以向你

vijosP1006 晴天小猪历险记之Hill

链接:https://vijos.org/p/1006 [思路] 图上DP. 这个题的递推顺序是关键.先从上一行得到最小值,然后从本行比较最小值,注意本行.本行与上一行之间的第一段与最后一段是相通的. [代码] 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #define FOR(a,b,c) for(int a=(b);a<=(c);a++) 5 using namespace std

[DP][vijos1006]晴天小猪历险记之Hill

题目梗概 首先题目和数字三角形那道经典的DP题目描述一样,不过增加了两处不同: 1.同行之间可以相邻移动 2.位置(i,j)(i,j),它与(i-1,j-1)(i−1,j−1)以及(i-1,j)(i−1,j)相邻,特别的(i,1)(i,1)与(i-1,i-1)(i−1,i−1)相邻,且(i,i)(i,i)与(i-1,1)(i−1,1)相邻. 思考 首先第一点我们只要在数字三角形的基础上,加上每行的移动就可以了. 但是第二点就要注意了,这样的描述使DP变成了环形. 具体的解释看这位大佬(Powde

hash+链表

简单的hash就是用数组加链表的组合来实现,这种hash很简单,但hash的思想在那. #ifndef _HASH_H_ #define _HASH_H_ typedef struct _ListNode { struct _ListNode *prev; struct _ListNode *next; void *data; }ListNode; typedef ListNode *List; typedef ListNode *Position; typedef struct _HashTb

Algorithm | hash

A basic requirement is that the function should provide a uniform distribution of hash values. A non-uniform distribution increases the number of collisions and the cost of resolving them. A critical statistic for a hash table is called the load fact

关于八数码问题中的状态判重的三种解决方法(编码、hash、&lt;set&gt;)

八数码问题搜索有很多高效方法:如A*算法.双向广搜等 但在搜索过程中都会遇到同一个问题,那就是判重操作(如果重复就剪枝),如何高效的判重是8数码问题中效率的关键 下面关于几种判重方法进行比较:编码.hash.set 看到问题初学者最先想到的应该就是用一个vis数组标志一下即可.但是该申请多大的数组呢?一个9维数组(9^9=387420489太大了吧)?如果内存允许这是最高效的办法:O(1) 所以我们现在面临的问题是如何在O(1)的时间复杂度不变的情况下把空间压缩下来: 方法一:编码.解码,我们可

大厂面试必问!HashMap 怎样解决hash冲突?

HashMap冲突解决方法比较考验一个开发者解决问题的能力. 下文给出HashMap冲突的解决方法以及原理分析,无论是在面试问答或者实际使用中,应该都会有所帮助. 在Java编程语言中,最基本的结构就是两种,一种是数组,一种是模拟指针(引用),所有的数据结构都可以用这两个基本结构构造,HashMap也一样. 当程序试图将多个 key-value 放入 HashMap 中时,以如下代码片段为例: HashMap<String,Object>m=newHashMap<String,Objec