zoukankan      html  css  js  c++  java
  • 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-k);
    43         else
    44         {
    45             cnt = 1;
    46             a[0] = n;
    47             memset(vis,0,sizeof(vis));
    48             vis[n] = 1;
    49             printf("%d
    ",bfs(0,0));
    50         }
    51     }
    52     return 0;
    53 }
    View Code
  • 相关阅读:
    英文词频统计
    字符串练习
    第八周
    第七周
    第五周
    第六周
    第三周
    第四周
    第二周
    第一周作业
  • 原文地址:https://www.cnblogs.com/Taskr212/p/10325701.html
Copyright © 2011-2022 走看看