HDU 1195 Open the Lock (双宽搜索)
2015-07-19 10:49
549 查看
意甲冠军:给你一个初始4数字和目标4数字,当被问及最初的目标转换为数字后,。
变换规则:每一个数字能够加1(9+1=1)或减1(1-1=9),或交换相邻的数字(最左和最右不是相邻的)。
双向广搜:分别对初始和目标数字进行广搜,vis数组用1和2标记两种已搜索的数字,用mp数组记录状态的步数。
当从前往后搜能够到达2或从后往前搜能够到达1状态则就能够了。。。
变换规则:每一个数字能够加1(9+1=1)或减1(1-1=9),或交换相邻的数字(最左和最右不是相邻的)。
双向广搜:分别对初始和目标数字进行广搜,vis数组用1和2标记两种已搜索的数字,用mp数组记录状态的步数。
当从前往后搜能够到达2或从后往前搜能够到达1状态则就能够了。。。
#include<stdio.h> #include<string.h> #include<string> #include<queue> #include<map> #include<iostream> #include<algorithm> using namespace std; struct node { int a[4]; int step; }s,e; int vis[10001];//标记当前状态是否有走过(从前往后走为1,从后往前走为2。没有走过为0) int mp[10001];//标记走到当前状态的步数 int get_num(int c[]) { int n=0; for(int i=0;i<4;i++) { n*=10; n+=c[i]; } return n; } int bfs() { memset(vis,0,sizeof(vis)); memset(mp,0,sizeof(mp)); queue<node>p,q; int tmp; tmp=get_num(s.a); vis[tmp]=1; tmp=get_num(e.a); vis[tmp]=2; node u,v; p.push(s); q.push(e); while(!q.empty()||!p.empty()) { if(!p.empty()) { u=p.front(); p.pop(); for(int i=0;i<4;i++) { v=u; v.a[i]=u.a[i]+1;//+1 if(v.a[i]==10) v.a[i]=1; tmp=get_num(v.a); if(vis[tmp]==0)//从前往后没有走过 { v.step=u.step+1; mp[tmp]=v.step;//标记走到当前状态的步数 vis[tmp]=1; p.push(v); } else if(vis[tmp]==2)//从前往后与从后往前有交叉 return u.step+mp[tmp]+1; v.a[i]=u.a[i]-1;//-1 if(v.a[i]==0) v.a[i]=9; tmp=get_num(v.a); if(vis[tmp]==0) { v.step=u.step+1; mp[tmp]=v.step; vis[tmp]=1; p.push(v); } else if(vis[tmp]==2) return u.step+mp[tmp]+1; } for(int i=0;i<3;i++)//交换 { v=u; int k=v.a[i]; v.a[i]=v.a[i+1]; v.a[i+1]=k; tmp=get_num(v.a); if(vis[tmp]==0) { v.step=u.step+1; mp[tmp]=v.step; vis[tmp]=1; p.push(v); } else if(vis[tmp]==2) return u.step+mp[tmp]+1; } } if(!q.empty()) { u=q.front(); q.pop(); for(int i=0;i<4;i++) { v=u; v.a[i]=u.a[i]+1; if(v.a[i]==10) v.a[i]=1; tmp=get_num(v.a); if(vis[tmp]==0) { v.step=u.step+1; mp[tmp]=v.step; vis[tmp]=2; q.push(v); } else if(vis[tmp]==1)//从后往前与从前往后哟交叉 return u.step+mp[tmp]+1; v.a[i]=u.a[i]-1; if(v.a[i]==0) v.a[i]=9; tmp=get_num(v.a); if(vis[tmp]==0) { v.step=u.step+1; mp[tmp]=v.step; vis[tmp]=2; q.push(v); } else if(vis[tmp]==1) return u.step+mp[tmp]+1; } for(int i=0;i<3;i++) { v=u; int k=v.a[i]; v.a[i]=v.a[i+1]; v.a[i+1]=k; tmp=get_num(v.a); if(vis[tmp]==0) { v.step=u.step+1; mp[tmp]=v.step; vis[tmp]=2; q.push(v); } else if(vis[tmp]==1) return u.step+mp[tmp]+1; } } } } int main() { int t; scanf("%d",&t); while(t--) { char s1[10],s2[10]; scanf("%s%s",s1,s2); for(int i=0;i<4;i++) s.a[i]=s1[i]-'0'; for(int i=0;i<4;i++) e.a[i]=s2[i]-'0'; s.step=0; e.step=0; printf("%d\n",bfs()); } return 0; } /* 99 1221 1212 */
相关文章推荐
- Linux-vim-encoding
- eclipse下修改项目名导致tomcat内发布名不一致的解决方法
- HDU 1011 Starship Troopers (树形DP+背包)
- Hadoop—MapReduce计算气象温度等例子---练习
- Hadoop伪分布式与集群式安装配置
- Hadoop—HDFS读写文件操作---练习4
- AT PPP拨号失败,linux环境下在如何调试?
- Linux svnserver存储路径和文件的详细解释
- POJ 2112 Optimal Milking(最大流)
- Hadoop--Hadoop2.X编译安装和实验------练习3
- php5.4.43开发环境的搭建(php5.4.43,apache2.2,mysql5.6以及phpMyAdmin)
- 嵌入式Linux module之符号导出
- Android Binder-涉及到Linux kernel相关知识点
- 在 CentOS 6.x上安装 docker.io成功
- linux下安装python
- 架构:层次化
- Shell编程中括号判断中赋值语句和判断语句
- jsoncpp在linux下的配置
- linux下添加用户并赋予root权限
- 嵌入式Linux模块的参数传递与多文件模块Makefile