题目描述
难度分:1400
输入T(≤2×104)表示T组数据。
每组数据输入n(1≤n≤109)和m(1≤m≤109)。
你有n个一样的苹果,要均分给m个小朋友,每个小朋友分到的量必须是一样的。
每次操作,你可以把一个苹果切开,得到两个一样的苹果块;或者,把一个苹果块一分为二,得到两个更小的苹果块。
你最少要操作多少次?如果无法做到,输出−1。
输入样例
4
10 5
1 5
10 4
3 4
输出样例
0
-1
2
5
算法
数学
由于每次操作都只能让所得苹果的重量增加12x,因此nm的最简分式的分母一定是2的次幂,不是就肯定无解。
下面考虑有解的情况,首先把n个苹果每个人分⌊nm⌋个(⌊.⌋表示对.向下取整,这个就是每个人分到的整苹果数,除了分出去的整苹果,剩下的苹果分到每个人手上都不是完整的),n个苹果就只剩下n%m个,将n更新为这个余数。
此时问题就相当于把剩下的n个苹果又均分给m个人,先每个切一刀,操作数增加n,然后苹果的块数会变为原来的两倍即2n。这时候问题就转变为将2n个苹果平均分配给m,相当于出现子问题,又分出去m块,让2n对m取模更新成新的n(剩下2n%m)。如此反复直到n变成0,停止操作。
复杂度分析
时间复杂度
算法过程中n需要反复对m取模,因此时间复杂度大概就是O(logmn)级别。
空间复杂度
整个算法用迭代实现,仅使用了有限的几个变量,额外空间复杂度为O(1)。
python 代码
from math import gcd
t = int(input())
for _ in range(t):
n, m = map(int, input().split())
g = gcd(n, m)
x = m // g
if x == (x&-x):
cur = n // m
n = n % m
ans = 0
while n > 0:
ans += n
n = n * 2 % m
print(ans)
else:
print(-1)