题目描述
兔子经常感到饥饿,所以当他们外出吃胡萝卜时,他们会尽快跳起来。
胡萝卜种植在一条数轴上。
最初,兔子站在整数位置init。设兔子当前位置在整数x,她可以在单次跳跃中跳到位置4 * x+3或位置8 * x+7。它最多可以跳跃100000次。
胡萝卜种植在x位置,当且仅当x可被1000000007整除时(即胡萝卜种植在0号位置,位置1000000007,位置2000000014,依此类推)。
输出兔子能吃到胡萝卜所需的最小跳跃次数。如果使用最多100,000次跳跃无法获得胡萝卜,则返回-1。
输入格式
多组测试数据。
第一行,一个整数G,表示有G组测试数据。 1 <= G <= 5
每组测试数据格式:
第一行,一个整数:init。 1<=init<=1000000006
输出格式
共G行,每行一个整数。
输入样例
5
125000000
281250001
974579565
18426114
4530664
输出样例
1
2
-1
58
478
题解
易得$4x + 3 = 2(2x + 1) + 1$, $8x + 7 = 2(2(2x + 1) + 1) + 1$,则$(4x + 3)^{3} = (8x + 7)^{2}$。
据此我们可以推出要尽可能使用“$8x + 7$”, 枚举使用“$8x + 7$”的次数,再分别枚举使用$0$~$2$次“$4x + 3$”即可。
#include <iostream> #include <cstdio> #define MAX_N (1000 + 5) using namespace std; const int mod = 1000000007; const int lim = 100000; int T; int x; int ans; int main() { cin >> T; int tmp; while(T--) { ans = lim + 1; cin >> x; for(register int i = 1; i <= lim && i <= ans; ++i) { tmp = x; for(register int j = 1; j < 3 && i + j - 1 <= lim && i + j - 1 <= ans; ++j) { tmp = (4LL * tmp + 3) % mod; if(!tmp) ans = min(ans, i + j - 1); } x = (8LL * x + 7) % mod; if(!x) ans = min(ans, i); } if(ans > lim) cout << "-1 "; else cout << ans << " "; } return 0; }