一道hash题
来源:互联网 发布:网络嗅探器 安卓 编辑:程序博客网 时间:2024/05/21 21:36
Description
春天到了,百花齐放,西湖公园里新设置了许多花坛,设计师想用不同的花摆出不同的图案以吸引游人,于是设计了各种图案并且在花圃中选好了要摆放的花。不幸的是负责搬运和摆放的工人因为临时有事,只将花放到花架上就匆匆离开了,并没有按照设计师原来的设计方案摆放,结果花坛杂乱不堪,设计师只好自己来调整花的位置。由于设计师通常从事脑力劳动,较少从事搬运和摆放花盆的体力工作,所以请你帮忙找出一种移动方法使工作量最小。
不同种类的花有不同的类型编号,虽然地球上花的种类很多,但因为公园里的花不超过1,000,000种,所以花的类型编号不超过1,000,000。另一方面,出于美学考虑,一个花坛里摆放的不同种类的花不超过3种,且不同种类的花的数量不可太接近,对于任意两种花,数量多的花的盆数至少是数量少的花的2倍。
花坛是正六边形的,共摆放有19盆花,每盆花都放在一个转盘上,转动一盆花下面的转盘,会使周围的6盆花顺时针或逆时针移动一个位置(但不可把花转到花坛外),称为一次操作。你的任务:用最少的操作使花坛由初始状态转化为符合设计图纸的目标状态。 例如:
初始状态 目标状态
如图,只需将处于圆心位置的那盆花的转盘顺时针转动一个位置,红色的花就移动到了目标位置。
Input Format
输入文件共11行,1-5行描述花坛的初始状态,7-11行表示花盆应摆放的位置。中间以空行分隔。5行数字分别表示花坛的5个行,其中第1、5两行有3个整数,第2、4两行有4个整数,第3行有5个整数,表示每一行的花的类型,不同的数代表不同种类的花。
Output Format
输出文件第一行包含一个整数T即最少的操作数,数据保证20步之内有解。以下T行输出操作序列,每行代表一次操作,包括3个整数 , , ,( , )表示第i步转动第 行,第 盆花下的转盘,当 为0时表示向顺时针方向转动, 为1时表示向逆时针方向转动,如有多种方案,任意输出其中一种即可。
Sample Input
1 1 1
1 2 1 1
1 1 1 1 1
1 1 1 1
1 1 1
1 1 1
1 1 1 1
1 1 2 1 1
1 1 1 1
1 1 1
Sample Output
1
3 2 0
思路:很明显这是一道广搜题,但如果是普通的搜,就会超时。
我们可以发现,在广搜的时候,会搜到很多重复的状态,因此多了很多的时间复杂度,那么我们可以将这些状态存下来,然后在搜索的时候判断是否搜过,便能减少很多复杂度。
这里介绍一种处理方法:hash。
就是根据数字的特征去存储数据,这样查找起来方便,特别对于大数字但是数据量少的时候,就格外好用(类似于离散化)
但是坑爹的是,这道题普通的hash还过不了。必须要加上链表优化。
我们在普通hash的时候,若这一位有用过,那么就单纯的+1就好了。
这样显然会很慢。那么我们就通过一种链表的方法:把同余的点连起来,那么我们在查找这个点是否被存过的时候,就非常快。
ps:这题的状态用3进制表示起来更加省空间,不然会爆空间的样子233
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<queue>#include<algorithm>#include<stack>#define N 1300000#define MOD 806871typedef long long LL;struct aa{ int x,id;}c[21];int yz[21],mz[21],b[9],next[N],tou[N],head,tail,bs[N];LL q[N],cs,mb;bool cmp(aa x,aa y){return x.x<y.x;}void ha(LL x){ int j=x%MOD; if (!tou[j]){ tou[j]=tail+1; q[++tail]=x; bs[tail]=bs[head]+1; return; } int last; j=tou[j]; while (j){ if (q[j]==x)return; last=j; j=next[j]; } next[last]=tail+1; q[++tail]=x; bs[tail]=bs[head]+1; return;}LL rturn(int x,int zt){ LL sta=q[zt]; int bz[29]; for (int i=19;i>=1;i--)bz[i]=sta%3,sta/=3; if (x==5||x==6){ int p=bz[x-4]; bz[x-4]=bz[x-1];bz[x-1]=bz[x+4];bz[x+4]=bz[x+5];bz[x+5]=bz[x+1];bz[x+1]=bz[x-3];bz[x-3]=p; LL xx=0; for (int i=1;i<=19;i++) xx=xx*3+bz[i]; return xx; } if (x==9||x==10||x==11){ int p=bz[x-5]; bz[x-5]=bz[x-1];bz[x-1]=bz[x+4];bz[x+4]=bz[x+5];bz[x+5]=bz[x+1];bz[x+1]=bz[x-4];bz[x-4]=p; LL xx=0; for (int i=1;i<=19;i++) xx=xx*3+bz[i]; return xx; } if (x==14||x==15){ int p=bz[x-5]; bz[x-5]=bz[x-1];bz[x-1]=bz[x+3];bz[x+3]=bz[x+4];bz[x+4]=bz[x+1];bz[x+1]=bz[x-4];bz[x-4]=p; LL xx=0; for (int i=1;i<=19;i++) xx=xx*3+bz[i]; return xx; } return 0;}LL lturn(int x,int zt){ LL sta=q[zt]; int bz[29]; for (int i=19;i>=1;i--)bz[i]=sta%3,sta/=3; if (x==5||x==6){ int p=bz[x-1]; bz[x-1]=bz[x-4];bz[x-4]=bz[x-3];bz[x-3]=bz[x+1];bz[x+1]=bz[x+5];bz[x+5]=bz[x+4];bz[x+4]=p; LL xx=0; for (int i=1;i<=19;i++) xx=xx*3+bz[i]; return xx; } if (x==9||x==10||x==11){ int p=bz[x-1]; bz[x-1]=bz[x-5];bz[x-5]=bz[x-4];bz[x-4]=bz[x+1];bz[x+1]=bz[x+5];bz[x+5]=bz[x+4];bz[x+4]=p; LL xx=0; for (int i=1;i<=19;i++) xx=xx*3+bz[i]; return xx; } if (x==14||x==15){ int p=bz[x-1]; bz[x-1]=bz[x-5];bz[x-5]=bz[x-4];bz[x-4]=bz[x+1];bz[x+1]=bz[x+4];bz[x+4]=bz[x+3];bz[x+3]=p; LL xx=0; for (int i=1;i<=19;i++) xx=xx*3+bz[i]; return xx; } return 0;}void bfs(LL x){ head=0;tail=0; ha(x); while (head<=tail){ head++; for (int i=1;i<=7;i++){ LL ls=lturn(b[i],head); ha(ls); if (ls==mb){ printf("%d\n",bs[tail]); exit(0); } LL rs=rturn(b[i],head); ha(rs); if (rs==mb){ printf("%d\n",bs[tail]); exit(0); } } }}int main(){ #ifndef ONLINE_JUDGE freopen("flowers.in","r",stdin); freopen("flowers.out","w",stdout); #endif for (int i=1;i<=19;i++)scanf("%d",&c[i].x),c[i].id=i; std::sort(c+1,c+20,cmp); bs[0]=-1; int j=-1; c[0].x=-1;; for (int i=1;i<=19;i++) if (c[i].x!=c[i-1].x)yz[c[i].id]=++j;else yz[c[i].id]=j; for (int i=1;i<=19;i++)scanf("%d",&c[i].x),c[i].id=i; std::sort(c+1,c+20,cmp); b[1]=5;b[2]=6;b[3]=9;b[4]=10;b[5]=11;b[6]=14;b[7]=15; j=-1; for (int i=1;i<=19;i++) if (c[i].x!=c[i-1].x)mz[c[i].id]=++j;else mz[c[i].id]=j; for (int i=1;i<=19;i++)cs=cs*3+yz[i]; for (int i=1;i<=19;i++)mb=mb*3+mz[i]; if (cs==mb){ printf("0"); return 0; } bfs(cs); return 0;}
- 一道hash题
- POJ-1200 Crazy Search,人生第一道hash题!
- 一道有趣的Hash加数学思想
- HDU 1496 (第一道hash附带讲解)
- 一道题
- 一道题
- 一道题
- 一道题
- 一道题
- 一道题
- 一道题
- 一道题
- 一道题
- 一道题
- 一道题
- 一道题
- 一道题
- 一道题
- Android的Message机制(简单小结)
- Chapter1 《第一个简单到IOS应用》
- Hadoop 第一次无法启动
- 二分法查找的Python实现
- MAC层与llc层的区别
- 一道hash题
- spring+mybatis整合时占位符无法读取jdbc.properties的问题
- JAVA之工厂模式
- hdoj 5478 Can you find it 【找恒等式 + 快速幂】
- 项目带给我的成长
- 归并链表
- HashMap的嵌套使用
- 在函数内栈上申请大数组导致发生段错误
- python http