HDU 2717(* bfs)

题意是在一个数轴上,每次可以一步到达当前位置数值的 2 倍的位置或者数值 +1 或数值 -1 的位置,给定 n 和 k,问从数值为 n 的位置最少多少步可以到达数值为 k 的位置。

用广搜的方法,把已经到达的位置标记,检查三个方向(*2,+1,-1)的位置是否到达 k,如已经到达就返回遍历的层数,否则将新的位置标记,继续检查新位置的三个方向。

这题要注意剪枝,每次的新位置要大于 0 小于 1e6,且当 n 大于 k 的时候要特殊处理,此时只能通过 -1 的方法到达 k,故输出 n - k 即可。

代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int n,k,cnt,a[100005];
 5 bool vis[100005];
 6 int bfs(int from,int times)
 7 {
 8 
 9     int ccnt = cnt;
10     for(int i = from; i < ccnt; ++i)
11     {
12         if(a[i]*2==k || a[i]+1==k || a[i]-1==k)
13             return ++times;
14         else
15         {
16             if(a[i]*2<=100000&&(!vis[a[i]*2]))
17             {
18                 a[cnt++] = a[i]*2;
19                 vis[a[i]*2] = 1;
20             }
21             if(a[i]-1>=0&&(!vis[a[i]-1]))
22             {
23                 a[cnt++] = a[i]-1;
24                 vis[a[i]-1] = 1;
25             }
26             if(a[i]+1<=100000&&(!vis[a[i]+1]))
27             {
28                 a[cnt++] = a[i]+1;
29                 vis[a[i]+1] = 1;
30             }
31         }
32     }
33     return bfs(ccnt,++times);
34 }
35 int main()
36 {
37     while(~scanf("%d %d",&n,&k))
38     {
39         if(n==k)
40             puts("0");
41         else if(n>k)
42             printf("%d\n",n-k);
43         else
44         {
45             cnt = 1;
46             a[0] = n;
47             memset(vis,0,sizeof(vis));
48             vis[n] = 1;
49             printf("%d\n",bfs(0,0));
50         }
51     }
52     return 0;
53 }
View Code

 

posted @ 2019-01-31 23:53  Taskr  阅读(225)  评论(0编辑  收藏  举报
Live2D