[编程题]-饥饿的小易
[
解题思路
]
小易的移动公式
:
f
(
x
)
=
4
*
x
+
4
g
(
x
)
=
8
*
x
+
7
计算可以得出两个规律:
1.
g
(
f
(
x
))
=
f
(
g
(
x
))
即
f
和
g
的执行顺序没有影响
2.
f
(
f
(
f
(
x
)))
=
g
(
g
(
x
))
即做
3
次
f
的变换等价于做
2
次
g
的变换
由规律
1
可以得出对于一个可行方案,可以调整其变换顺序。比如:
ffffggfggffff
可以转换为
fffffffffgggg
由规律
2
并且为了减少执行次数,每
3
个
f
可以转换为
2
个
g
如方案
fffffffffgggg
可以转换为
ffffgggggg.
因此一个最优的策略:
f
的执行次数为
0
,
1
,
2
。 对于输入
x
, 只需要要求
x , 4x+3, 4(4x+3)+3
的最小
g
执行
次数即可。
[
示例代码
]
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
long x0 = scanner.nextLong();
long m = 1000000007;//取模的值
long s = 100000; //神秘力量使用的次数
long[] begin = new long[3]; //f(x) = 4x+3 执行3次
//3次的取值
begin[0] = x0;
begin[1] = (4 * begin[0] + 3) % m;
begin[2] = (4 * begin[1] + 3) % m;
long minStep = s;
long cur = 0;
int step = 0; //执行的步数
for (int i = 0; i < 3; i++) {
cur = begin[i];
step = i;
while (cur != 0 && step < minStep) {
cur = (8 * cur + 7) % m; //g(x) = 8x+7 执行
step++;
}
minStep = minStep < step ? minStep : step;
}
if (minStep < s) { //如果执行步长没有超过s输出最小步长
System.out.println(minStep);
} else {//超过返回-1
System.out.println(-1);
}
}
}