刚学了个双向BFS,顺便用这题来练习练习,看看效果如何。
先来个单向bfs。
用时62ms。
下面是单向BFS代码。这次写的很顺利,基本一次性写完没有调试提交就AC了。。
#include <stdio.h> #include <string.h> #include <queue> #include <math.h> using namespace std; int vis[100000], a[5], b[5]; char s1[5], s2[5]; int jj[]= {1,-1}; struct node { int a[5], ans; }; int pan(int a[]) { int x=0, i; for(i=0; i<4; i++) x=x*10+a[i]; return x; } void bfs() { node f1, f2; queue<node>q; int i, j, k; for(i=0; i<4; i++) f1.a[i]=a[i]; f1.ans=0; q.push(f1); vis[pan(f1.a)]=1; while(!q.empty()) { f1=q.front(); q.pop(); if(pan(f1.a)==pan(b)) { printf("%d\n",f1.ans); return ; } for(i=0; i<4; i++) f2.a[i]=f1.a[i]; for(i=0; i<4; i++) { for(j=0; j<2; j++) { for(k=0; k<4; k++) f2.a[k]=f1.a[k]; f2.a[i]=f1.a[i]+jj[j]; if(f2.a[i]==10) f2.a[i]=1; if(f2.a[i]==0) f2.a[i]=9; if(!vis[pan(f2.a)]) { vis[pan(f2.a)]=1; f2.ans=f1.ans+1; q.push(f2); } } } for(i=0; i<3; i++) { for(k=0; k<4; k++) f2.a[k]=f1.a[k]; int t=f2.a[i]; f2.a[i]=f2.a[i+1]; f2.a[i+1]=t; if(!vis[pan(f2.a)]) { vis[pan(f2.a)]=1; f2.ans=f1.ans+1; q.push(f2); } } } } int main() { int t, i; scanf("%d ",&t); while(t--) { memset(vis,0,sizeof(vis)); scanf("%s",s1); for(i=0; i<4; i++) a[i]=s1[i]-'0'; scanf("%s",s2); for(i=0; i<4; i++) b[i]=s2[i]-'0'; bfs(); } return 0; }
这是双向BFS
用时15ms
时间上没有想象中的那么快。。但是还不错。。可能是数据比较小吧,按理说数据越大优势越明显。
双向BFS也就只是用了两个BFS同时搜索而已,一个从起点往终点找,一个从终点往起点找,然后当出现交集时便是找到了。代码如下:
#include <stdio.h> #include <string.h> #include <queue> #include <math.h> using namespace std; int a[5], b[5]; char s1[5], s2[5]; int jj[]= {1,-1}; struct node { int a[5], ans; }; struct N { int x; int flag; } vis[100003]; int pan(int a[]) { int x=0, i; for(i=0; i<4; i++) x=x*10+a[i]; return x; } void bfs() { node f1, f2; queue<node>q1; queue<node>q2; int i, j, k; for(i=0; i<4; i++) f1.a[i]=a[i]; f1.ans=0; q1.push(f1); vis[pan(f1.a)].flag=1; vis[pan(f1.a)].x=0; for(i=0; i<4; i++) f1.a[i]=b[i]; f1.ans=0; q2.push(f1); vis[pan(f1.a)].flag=2; vis[pan(f1.a)].x=0; int st=0; while(!q1.empty()&&!q2.empty()) { while(q1.front().ans==st) { f1=q1.front(); //printf("%d\n",f1.ans); q1.pop(); for(i=0; i<4; i++) { for(j=0; j<2; j++) { for(k=0; k<4; k++) f2.a[k]=f1.a[k]; f2.a[i]=f1.a[i]+jj[j]; if(f2.a[i]==10) f2.a[i]=1; if(f2.a[i]==0) f2.a[i]=9; f2.ans=f1.ans+1; if(!vis[pan(f2.a)].flag) { vis[pan(f2.a)].flag=1; vis[pan(f2.a)].x=f2.ans; q1.push(f2); } else if(vis[pan(f2.a)].flag==2) { printf("%d\n",f2.ans+vis[pan(f2.a)].x); return ; } } } for(i=0; i<3; i++) { for(k=0; k<4; k++) f2.a[k]=f1.a[k]; int t=f2.a[i]; f2.a[i]=f2.a[i+1]; f2.a[i+1]=t; f2.ans=f1.ans+1; if(!vis[pan(f2.a)].flag) { vis[pan(f2.a)].flag=1; vis[pan(f2.a)].x=f2.ans; q1.push(f2); } else if(vis[pan(f2.a)].flag==2) { printf("%d\n",f2.ans+vis[pan(f2.a)].x); return ; } } } while(q2.front().ans==st) { f1=q2.front(); q2.pop(); //printf("%d\n",f1.ans); for(i=0; i<4; i++) { for(j=0; j<2; j++) { for(k=0; k<4; k++) f2.a[k]=f1.a[k]; f2.a[i]=f1.a[i]+jj[j]; if(f2.a[i]==10) f2.a[i]=1; if(f2.a[i]==0) f2.a[i]=9; f2.ans=f1.ans+1; if(!vis[pan(f2.a)].flag) { vis[pan(f2.a)].flag=2; vis[pan(f2.a)].x=f2.ans; q2.push(f2); } else if(vis[pan(f2.a)].flag==1) { printf("%d\n",f2.ans+vis[pan(f2.a)].x); return ; } } } for(i=0; i<3; i++) { for(k=0; k<4; k++) f2.a[k]=f1.a[k]; int t=f2.a[i]; f2.a[i]=f2.a[i+1]; f2.a[i+1]=t; f2.ans=f1.ans+1; if(!vis[pan(f2.a)].flag) { vis[pan(f2.a)].flag=2; vis[pan(f2.a)].x=f2.ans; q2.push(f2); } else if(vis[pan(f2.a)].flag==1) { printf("%d\n",f2.ans+vis[pan(f2.a)].x); return ; } } } st++; } } int main() { int t, i; scanf("%d ",&t); while(t--) { for(i=0;i<100002;i++) vis[i].flag=0; scanf("%s",s1); for(i=0; i<4; i++) a[i]=s1[i]-'0'; scanf("%s",s2); for(i=0; i<4; i++) b[i]=s2[i]-'0'; bfs(); } return 0; }