题目
总时间限制: 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(){