• poj3278-Catch That Cow 【bfs】


    http://poj.org/problem?id=3278

    Catch That Cow
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 52463   Accepted: 16451

    Description

    Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.

    * Walking: FJ can move from any point X to the points - 1 or + 1 in a single minute
    * Teleporting: FJ can move from any point X to the point 2 × X in a single minute.

    If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?

    Input

    Line 1: Two space-separated integers: N and K

    Output

    Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.

    Sample Input

    5 17

    Sample Output

    4

    Hint

    The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.
     
     
     
    题解:最短路,第一想法是bfs,简单易操作。这里需要说明一下就是,这道题目的边界不需要扩充,理由嘛,看下面0ms代码的注释吧。再次强调,STL少用,这里再次验证了其效率的低下。
    代码一:【127ms】bfs暴搜+STL里的queue:
     1 #include <fstream>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cstdio>
     5 #include <cstring>
     6 #include <cmath>
     7 #include <cstdlib>
     8 #include <queue>
     9 
    10 using namespace std;
    11 
    12 #define PI acos(-1.0)
    13 #define EPS 1e-10
    14 #define lll __int64
    15 #define ll long long
    16 #define INF 0x7fffffff
    17 
    18 queue<pair<int,int> > qu;
    19 bool b[100002];
    20 
    21 inline bool Check(int x);
    22 int Bfs(int r1,int r2);
    23 
    24 int main(){
    25     //freopen("D:\input.in","r",stdin);
    26     //freopen("D:\output.out","w",stdout);
    27     int r1,r2;
    28     scanf("%d %d",&r1,&r2);
    29     printf("%d
    ",Bfs(r1,r2));
    30     return 0;
    31 }
    32 inline bool Check(int x){
    33     return x>=0&&x<=100000&&b[x]==0;
    34 }
    35 int Bfs(int r1,int r2){
    36     qu.push(make_pair(r1,0));
    37     b[r1]=1;
    38     while(!qu.empty()){
    39         pair<int,int> tmp=qu.front();
    40         qu.pop();
    41         if(tmp.first==r2){
    42             return tmp.second;
    43         }
    44         int x=tmp.first+1;
    45         if(Check(x)){
    46             b[x]=1;
    47             qu.push(make_pair(x,tmp.second+1));
    48         }
    49         x=tmp.first-1;
    50         if(Check(x)){
    51             b[x]=1;
    52             qu.push(make_pair(x,tmp.second+1));
    53         }
    54         x=tmp.first*2;
    55         if(Check(x)){
    56             b[x]=1;
    57             qu.push(make_pair(x,tmp.second+1));
    58         }
    59     }
    60 }

    我自己底下实验了下,把STL去掉,自己实现简易的队列,再进行暴搜,时间消耗为16ms。

    代码二:【0ms】bfs剪枝(这里没有用STL):         剪枝内容:当自己的位置大于k的时候,自然不用考虑+1和*2的情况了。

     1 #include <fstream>
     2 #include <iostream>
     3 #include <cstdio>
     4 
     5 using namespace std;
     6 
     7 const int N=100005;
     8 int n,k,dis[N],queue[N];//dis:记录走到某个点的步数。 queue:因为每次队列采用去重加入,所以N是足够用了。
     9 bool b[N];//N是足够的,不需要扩展2N或者3N。打比说x先乘再减,与先减再乘,后者会更快,故不会超过N,负数是更不可能的,因为没有除法。
    10 
    11 int bfs();
    12 
    13 int main()
    14 {
    15     //freopen("D:\input.in","r",stdin);
    16     //freopen("D:\output.out","w",stdout);
    17     scanf("%d%d",&n,&k);
    18     printf("%d",bfs());
    19     return 0;
    20 }
    21 int bfs(){
    22     int l,r,x;
    23     l=r=0;
    24     dis[n]=0;
    25     queue[0]=n;
    26     while(1){//队列不可能为空
    27         if(queue[l]==k) return dis[k];
    28         if(x=queue[l]-1,x>=0&&!b[x]){//注意边界
    29             b[x]=1;
    30             queue[++r]=x;
    31             dis[x]=dis[queue[l]]+1;
    32         }
    33         if(x=queue[l]+1,queue[l]<=k&&!b[x]){//这里的queue[l]<=k为剪枝
    34             b[x]=1;
    35             queue[++r]=x;
    36             dis[x]=dis[queue[l]]+1;
    37         }
    38         if(x=queue[l]<<1,queue[l]<=k&&x<N&&!b[x]){//这里的queue[l]<=k为剪枝;注意边界
    39             b[x]=1;
    40             queue[++r]=x;
    41             dis[x]=dis[queue[l]]+1;
    42         }
    43         l++;
    44     }
    45 }
  • 相关阅读:
    关于跳板机登陆服务器一系列操作命令
    Linux环境搭建docker-selenium来运行UI自动化
    linux环境升级python2.7到python最新版本
    守护进程的理解--性能
    macbook添加webdriver驱动注意事项
    windows压测机本地端口号配置
    jmeter的bean shell 如何写数据到文件中
    Jenkins Pipeline介绍
    Jenkins创建Maven Job
    配置 Maven 项目使用 Nexus 仓库
  • 原文地址:https://www.cnblogs.com/jiu0821/p/4354571.html
Copyright © 2020-2023  润新知