您的位置:首页 > 运维架构

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状态则就能够了。。。

#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
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: