栈与队列#抓住那头牛

题目

总时间限制: 2000ms
内存限制: 65536kB
描述
农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N(0<=N<=100000),牛位于点K(0<=K<=100000)。农夫有两种移动方式:1、从X移动到X-1或X+1,每次移动花费一分钟2、从X移动到2*X,每次移动花费一分钟
假设牛没有意识到农夫的行动,站在原地不动。农夫最少要花多少时间才能抓住牛?
输入

两个整数,N和K

输出

一个整数,农夫抓到牛所要花费的最小分钟数
样例输入

5 17

样例输出

4

对题目的思考过程

当看到10W数据的时候,大致就知道时间复杂度得几乎线性了。
分析题目,要求达到时时间最小。
那么可能不可能是贪心
如果贪心,局部最优不可能得到全局最优,然后我想到了动态规划。可是动态规划我并不会运用。
再考虑题目,注意到是关于数据结构的题,所以纠正思维,往数据结构上去想。
无非是栈与队列,再次考虑,人与牛的关系,是的,不能互换;
模拟,递归,贪心,栈,队列,数论,思考各种东西。
突然意识到,操作无外乎三种,+1,-1,*2;
是的,可以暴力模拟,我们只要摆脱递归的高额复杂度,就能实现。
首先,我们试着打表模拟农民
农民站在5上

0 1 2 3 4 5 6 7 8 9 10 11
0 0 0 0 0 0 0 0 0 0 0 0

然后

0 1 2 3 4 5 6 7 8 9 10 11
0 0 0 0 1 0 1 0 0 0 1 0

然后

0 1 2 3 4 5 6 7 8 9 10 11
0 0 0 2 1 0 1 2 0 2 1 2

然后

0 1 2 3 4 5 6 7 8 9 10 11
5 4 3 2 1 0 1 2 3 2 1 2

一层层的推下去,我们注意到在模拟的时候,是有次序的。
这个次序的规律在模拟中可以看出来,是每次都要对上次产生的推断得到的三个数再进行三次推断。而且最重要的是顺序推断,顺序推断,所以要用队列。
可以得出次数大概是3,9,27,81…
每次走的步数,都相当于一个推断三次的轮回。

为了使得到的次数最小,我们要在推断中去判断这个数有没有在前面的推断中推出过,于是我们用一个map来标识;
再利用每次队列为空时,全局变量sum++来得到轮回的次数;

考虑到一个队列我们没办法判断一个轮回是否结束,我们采用两个队列。

int dl1[110000];
int *f1=dl1, *l1=dl1;
int dl2[110000];
int *f2=dl2, *l2=dl2;

在一个出列的时候,要将这个出列推出的三个数压入另一个队列,于是

void po1(){
   
 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值