版权声明:转载请注明来源 https://blog.csdn.net/tangyuan_sibal/article/details/88361383
今天做腾讯的暑假实习编程题,其中有一道题目是这样子的:
小Q的父母要出差N天,走之前给小Q留下了M块巧克力。小Q决定每天吃的巧克力数量不少于前一天吃的一半,但是他又不想在父母回来之前的某一天没有巧克力吃,请问他第一天最多能吃多少块巧克力
作为菜鸡的我只能跑出百分之二十的测试用例。。。。。。。
然后就按常例跑去讨论区看大佬的解法,有一个大佬用了二分查找来做这道题,只能说自己是真的菜,。。。思路都不对,更不要说用到二分查找了,大佬的思路是
小Q第一天肯定至少吃一块的,不然的话你这巧克力一块就可以吃一辈子了。。。,当然小Q最多也只能吃M块,总的也就那些。所以我们可以这样子设计,我们假设小Q在第一天吃了mid块,然后再N天能吃多少,如果刚好吃到M,这样就是我们要的结果,而且关键的是,小Q每天吃的巧克力是原来的一半,说明这是一个递增的数组,就是你mid越大,你能吃到的就越多是吧。所以我们在这个递增数组里面找到等于M的,这个时候就是查找的事情了,就可以用二分查找了
import java.util.Scanner;
public class Eating {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext())
{
int n = scanner.nextInt();
int m = scanner.nextInt();
int res = fun(n,m);
System.out.println(res);
}
}
//对这些可能吃的情况,用二分查找进行查找到正确值
public static int fun(int n,int m){
//如果只有出去一天,则直接返回m
if(n==1)
return m;
//每天吃的蛋糕数最少为1个,最多
int low = 1;
int high = m;
while(low<=high)
{
int mid = (low+high+1)>>1;//向上取整,用移位运算比计算的好
if(sum(mid,n)==m)return mid;
else if(sum(mid,n)<m)
low = mid;
else
high = mid;
}
return high;
}
//每天吃mid块,n天可以吃多少块
private static int sum(int mid,int n) {
int count = 0;
for(int i=0;i<n;i++)
{
count += mid;
mid = (mid+1)>>1;
}
return count;
}
}