POJ 3278 Catch That Cow

来源:互联网 发布:淘宝一元包邮怎么赚钱 编辑:程序博客网 时间:2024/06/18 15:32

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

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 X - 1 or X + 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.

Source
USACO 2007 Open Silver

大概题意:一条数轴人在n点,牛在k点。
人有3种走法:1.向前走一步 2.向后走一步 3.走2*n步
问人最少走几步可以抓到牛。

大概思路:我分类讨论了,但其实不讨论也没什么。
1.如果n>=k,那么人只能往后退,即走n-k步。
2.n>k,那么就bfs。这是我第一题bfs,真是看了很多很多的题解啊,简直要死。模板也不会套啊。

#include<stdio.h>#include<iostream>#include<queue>#include<string.h>using namespace std;bool vis[100005];    //记录是否被访问int step[100005];    //记录走到某一个点所需要的步数queue<int>q;         //队列。嗯,队列就是队列int bfs(int n,int k){    int now,next;    while(!q.empty())    //初始化……?        q.pop();    vis[n]=1;            //原点为n,所以标记访问过了    step[n]=0;           //n点时的步数也为0    q.push(n);           //进入队列    while(!q.empty())    {        now=q.front();               q.pop();        for(int i=0;i<3;i++)        {            if(i==0)  next=now-1;            else if(i==1)  next=now+1;            else next=now*2;            if(next<0||next>100005)  continue;            if(!vis[next])            {                q.push(next);                  vis[next]=1;                step[next]=step[now]+1;              }            if(next==k)  return  step[next];        }    }}int main(){    int n,k;    while(scanf("%d %d",&n,&k)!=EOF)    {        memset(vis,0,sizeof(vis));         //初始化        memset(step,0,sizeof(step));        if(n>=k)            printf("%d\n",n-k);        else            printf("%d\n",bfs(n,k));    }    return 0;}

虽然还是不太会,但是还是总结一下。
重要的是
1.设置几个数组。vis数组判断是否被访问,需要即时更新。
还有按情况而定,那个步数的数组也可以放在结构体里面。主要存放状态的一个数组。
2.步骤:
(1).初始化数组。
(2).对原点进行状态初始化,入队列。
(3).开始搜索。
(4).状态转移的过程,就是设定走的方式。
(5).超出范围就无需考虑,退出循环。
(6).没有被访问过的话,就设置新一步的状态。
(7).循环到想要的结果后就退出。
3.然后我按照这个步骤雄心壮志的看了第二题bfs,可以,很强势,依旧一脸懵逼……

这里写图片描述

1 0
原创粉丝点击