刚学了个双向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;
}