搜索 问题 D: 神奇密码锁
来源:互联网 发布:kanahei知乎 编辑:程序博客网 时间:2024/05/19 10:37
这道题个人认为隐含着状态转换,所以想到的还是BFS,将其中一位数加一或减一或交换临近两位,进入下一状态,使用一个大小为10000的bool数组判重,由于BFS的特性,得到的一定是最小步数;
普通BFS代码如下:
#include<iostream>#include<cstdio>#include<cstring>#include<set>using namespace std;const int MaxSize = 1e5;typedef struct node{ int a[4]; int step;}Node;Node Q[MaxSize];bool visit[10005];bool search_table(int *a){ int tmp=0; tmp = a[0]*1000+a[1]*100+a[2]*10+a[3]; if(visit[tmp])return false; visit[tmp] = true; return true;}int BFS(int *start,int *goal){ int head=0,tail=1,tmp; memset(visit,0,sizeof(visit)); Node t,s; memcpy(t.a,start,4*sizeof(int)); t.step = 0; Q[head] = t; while(head!=tail){ t = Q[head]; if(!memcmp(t.a,goal,4*sizeof(int))) return t.step; for(int i=0;i<4;i++){ s = t; s.a[i]++; s.step++; if(s.a[i]>9) s.a[i]=1; if(search_table(s.a)) { Q[tail]=s; tail=(tail+1)%MaxSize; } } for(int i=0;i<4;i++){ s = t; s.a[i]--; s.step++; if(s.a[i]<1) s.a[i]=9; if(search_table(s.a)) { Q[tail]=s; tail=(tail+1)%MaxSize; } } for(int i=0;i<3;i++){ s = t; tmp = s.a[i],s.a[i] = s.a[i+1],s.a[i+1] = tmp; s.step++; if(search_table(s.a)) { Q[tail]=s; tail=(tail+1)%MaxSize; } } head=(head+1)%MaxSize; } return -1;}void Input_data(int *start,int *goal){ char c[5]; scanf("%s",c); for(int i=0;i<4;i++) start[i] = c[i]-'0'; scanf("%s",c); for(int i=0;i<4;i++) goal[i] = c[i]-'0';}int main(){ int T,start[4],goal[4]; scanf("%d",&T); while(T--){ Input_data(start,goal); printf("%d\n",BFS(start,goal)); }}
双向BFS:
#include<iostream>#include<cstdio>#include<cstring>using namespace std;int visit[10005];const int MaxSize = 1e5;typedef struct node{ int a[4],step;}Node;Node start,goal;int trans(Node x){ int tmp = 0; for(int i=0;i<4;i++) tmp = tmp*10+x.a[i]; //printf("%d\n",tmp); return tmp;}Node Q1[MaxSize],Q2[MaxSize];int BFS(){ memset(visit,0,sizeof(visit)); //queue<Node> Q1,Q2; Node t,s; int step1=0,step2=0,ans,cnt; int head1=0,head2=0,tail1=1,tail2=1; start.step = 0; goal.step = 0; Q1[head1] = start; Q2[head2] = goal; visit[trans(start)]=1; visit[trans(goal)]=2; while(true){ cnt = (tail1-head1+MaxSize)%MaxSize; while(cnt--){ t = Q1[head1]; if(!memcmp(t.a,goal.a,sizeof(goal.a))) return t.step; step1 = t.step + 1; for(int i=0;i<4;i++){ s = t; s.a[i]++; if(s.a[i]>9) s.a[i]=1; ans = trans(s); if(visit[ans]==2) return step1+step2; if(!visit[ans]){ visit[ans] = 1; s.step = step1; Q1[tail1]=s; tail1=(tail1+1)%MaxSize; } } for(int i=0;i<4;i++){ s = t; s.a[i]--; if(s.a[i]<1) s.a[i]=9; ans = trans(s); if(visit[ans]==2) return step1+step2; if(!visit[ans]){ visit[ans] = 1; s.step = step1; Q1[tail1]=s; tail1=(tail1+1)%MaxSize; } } for(int i=0;i<3;i++){ s = t; swap(s.a[i],s.a[i+1]); ans = trans(s); if(visit[ans]==2) return step1+step2; if(!visit[ans]){ visit[ans] = 1; s.step = step1; Q1[tail1]=s; tail1=(tail1+1)%MaxSize; } } head1=(head1+1)%MaxSize; } cnt = (tail2-head2+MaxSize)%MaxSize; while(cnt--){ t = Q2[head2]; if(!memcmp(t.a,start.a,sizeof(start.a))) return t.step; step2 = t.step + 1; for(int i=0;i<4;i++){ s = t; s.a[i]++; if(s.a[i]>9) s.a[i]=1; ans = trans(s); if(visit[ans]==1) return step1+step2; if(!visit[ans]){ visit[ans] = 2; s.step = step2; Q2[tail2]=s; tail2=(tail2+1)%MaxSize; } } for(int i=0;i<4;i++){ s = t; s.a[i]--; if(s.a[i]<1) s.a[i]=9; ans = trans(s); if(visit[ans]==1) return step1+step2; if(!visit[ans]){ visit[ans] = 2; s.step = step2; Q2[tail2]=s; tail2=(tail2+1)%MaxSize; } } for(int i=0;i<3;i++){ s = t; swap(s.a[i],s.a[i+1]); ans = trans(s); if(visit[ans]==1) return step1+step2; if(!visit[ans]){ visit[ans] = 2; s.step = step2; Q2[tail2]=s; tail2=(tail2+1)%MaxSize; } } head2 = (head2+1)%MaxSize; } }}void Input_and_solve(){ char ch[5]; scanf("%s",ch); for(int i=0;i<4;i++) start.a[i] = ch[i]-'0'; scanf("%s",ch); for(int i=0;i<4;i++) goal.a[i] = ch[i]-'0'; printf("%d\n",BFS());}int main(){ int T; scanf("%d",&T); while(T--){ Input_and_solve(); }}//如有错误,还请留言指出
阅读全文
0 0
- 搜索 问题 D: 神奇密码锁
- 问题 D: 神奇密码锁
- 神奇密码锁
- 神奇密码锁
- 神奇密码锁 bfs
- 神奇密码锁(BFS)
- 密码锁问题
- 神奇密码锁 BFS (枚举) 进位转换 memcmp
- 密码锁
- 密码锁
- Openjudge 8469:特殊密码锁 暴力搜索
- openjudge 特殊密码锁(开关问题)
- 搜索 D
- 搜索--D
- 搜索 D
- 搜索-D
- 搜索-D
- 搜索 D
- poj 1039 直线与直线相交的问题
- 第七届福建省赛 FZU 2267 X(floyd)
- 错误小计
- Android控件postDelayed用法,View自带的定时器
- linux系统查看日志的几种方法
- 搜索 问题 D: 神奇密码锁
- CodeForces
- Servlet学习
- 简单算法整理
- XA协议
- 链表
- idea部署tomcat启动成功后访问一直提示404
- SQL逆向工程生成代码 2种方法可以根据Id 取到 Item对象
- C++中的 菱形继承