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

HDU 1195 Open the Lock (双向BFS)

2014-06-28 13:40 323 查看
题目链接:Open the Lock

题意:就是给定两个4位数,起始,结束。问从起始数字到达结束数字 最少变换多少步,每个数 可以+1 / -1 或交换位置,都算做是一步。

单广,双广都用了,感觉双向BFS,太棒了,HDU的这个题双向BFS时间优化的太棒了

有图,有真相!





时间优化了近9倍。。。

PS:今天还学习一个sscanf函数,挺棒的

单搜的代码就不贴了,贴个双搜的

#include<cstdio>
#include <iostream>
#include<cstring>
#include <queue>
const int N = 10001; //因为是1-9 4位数  所以10000肯定够
using namespace std;
int vis
;
int dis
;
struct node
{
char a[5];
};
char st[5],en[5];
void BFS()
{
queue<node>q;
node f,t;
strcpy(f.a,st);
q.push(f);
int w,mm;
sscanf(f.a,"%d",&w);
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
dis[w] = 0;
vis[w] = 1; // 从起点开始搜素的路线标记为1
strcpy(f.a,en);

q.push(f);
sscanf(f.a,"%d",&w);
dis[w] = 0;
vis[w] = 2;  //从终点开始搜素的路线标记为2

while(!q.empty())
{
t = q.front();
q.pop();

for(int i = 0;i<3;i++)
{
if(i==0)
{
sscanf(t.a,"%d",&mm);
for(int j = 0;j<=3;j++)
{
f = t;
if(f.a[j]=='9')  f.a[j] = '1';
else   f.a[j] += 1;
sscanf(f.a,"%d",&w);
if(!vis[w])
{
vis[w] = vis[mm];
dis[w] = dis[mm] + 1;
q.push(f);
}
else if(vis[w]!=vis[mm])
{
printf("%d\n",dis[w]+dis[mm]+1);
return ;
}
}
}
else if(i==1)
{
sscanf(t.a,"%d",&mm);
for(int j = 0;j<=3;j++)
{
f = t;
if(f.a[j]=='1')  f.a[j] = '9';
else   f.a[j] -= 1;
sscanf(f.a,"%d",&w);
if(!vis[w])
{
vis[w] = vis[mm];
dis[w] = dis[mm] + 1;
q.push(f);
}
else if(vis[w]!=vis[mm])
{
printf("%d\n",dis[w]+dis[mm]+1);
return ;
}
}
}
else if(i==2)
{
sscanf(t.a,"%d",&mm);
for(int j = 0;j<3;j++)
{
f = t;
char g = f.a[j];
f.a[j] = f.a[j+1];
f.a[j+1] = g;
sscanf(f.a,"%d",&w);
if(!vis[w])
{
vis[w] = vis[mm];
dis[w] = dis[mm] + 1;
q.push(f);
}
else if(vis[w]!=vis[mm])
{
printf("%d\n",dis[w]+dis[mm]); //  +1 /-1 两者相遇时都没变换状态,所以要加1步,而两数交换就是一步,所以不用加+
return ;
}
}
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s%s",st,en);
if(strcmp(st,en)==0)
printf("0\n");
else
BFS();
}
return 0;
}


测试数据,乱写的,以下都对了,应该就能AC

10

1234

6541

9

1111

1111

0

9999

9999

0

1111

1118

2

9911  

1199

3

9512

3258 

7

1238  

9845

7

1111

2222 

4

1111   

6666

16

9559  

9555

4

6554

4556

4
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: