题目描述
出题人作为苦逼的研究生被导师布置了一项任务,他的面前摆有n件物品,这n件物品中仅有一件物品比其他物品重。而出题人则拥有一个神奇天平,该天平最多可以放置m样东西,每次称量可以得出哪样东西最重,或者放置的若干样东西一样重。
现在出题人想知道,他至少称多少次一定能找出这件较重的物品?
输入
第一行一个正整数T,表示数据组数T≤1e5。
对于每组数据,输入两个整数n,m,2≤n≤1e9,2≤m≤1e9。
输出
对于每组数据,输出保证一定能找到较重物品的最少称量次数。
样例输入
2 9 2 8 2
样例输出
2 2
提示
对于样例1:
首先把9件物品分成三堆,每堆3件,然后将其中两堆放入神奇天平。若一样重则表示重的物品在没放入的那堆中,否则通过天平我们可以找到重的那堆。
把重的那堆三件物品中的其中两件再次放入神奇天平,若一样重则表示剩下的那件物品就是重的物品,否则通过天平我们可以找到重的那件物品。
样例2的答案可类比以上过程得到。
问题分析:给定n个物品,其中n-1个正常的,1个残次的,用有m个托(咱平常见的天平是2个托)的天平去称,问几次能称出来。
分堆策略:因为有m个托,所以分成m+1堆,因为如果残次品出现在天平上,那么直接就能够称出来,如果没在天平上,那么就在剩下的那一堆里。
问题重构:按照分堆策略,我们的问题就转化为找出最坏情况称一次之后n变成了几。如果11 2分应该是4 4 3那么最坏情况残次品会出现在4里面,所以n=4然后再分成1 1 2,再把2放天平上称也就是n=2,总次数三次。我们发现,在最坏情况下,残次品总应该是在分的最多的那里,也就是n/(m+1)向上取整。
关于向上取整:在c语言里有向上取整的函数ceil,大家可以自行学习使用。下面给出一个向上取整的数学原理:(n-1)/m +1 :被除数减一整除除数后加一;原理可以自己搜一下;
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
while(n--)
{
int x,y,res=0;
scanf("%d%d",&x,&y);
while(x != 1)
{
x = (x-1)/(y+1)+1;
res++;
}
printf("%d\n",res);
}
return 0;
}