小Q的父母要出差N天,走之前给小Q留下了M块巧克力。小Q决定每天吃的巧克力数量不少于前一天吃的一半,但是他又不想在父母回来之前的某一天没有巧克力吃,请问他第一天最多能吃多少块巧克力
输入描述:
每个输入包含一个测试用例。 每个测试用例的第一行包含两个正整数,表示父母出差的天数N(N<=50000)和巧克力的数量M(N<=M<=100000)。
输出描述:
输出一个数表示小Q第一天最多能吃多少块巧克力。
输入例子1:
3 7
输出例子1:
4
思路:
我们可以利用二分的思想找到满足题意(就是条件1,后一天吃的巧克力的个数至少为前一天的一半;条件二,需要在父母出差的这几天每天都有巧克力吃的到)得第一天吃得巧克力得个数。
举例1:
n=3 m=7
我们有七块巧克力
1 2 3 4 5 6 7
首先我们找到中间位置的巧克力个数(向上取整)(1+7+1)/2=4
就是4位置的巧克力
然后我们以它作为第一天的起始巧克力个数对这些天所需要的总巧克力个数进行求和,最终的结果总巧克力数目如果等于m那么直接返回4,如果小于m,那么可能存在更优的解在[5,7]区间内,那么需要在5位置到7位置中间位置继续做相同的操作。
如果大于m,那么证明我们第一天给的巧克力的数目太多了,需要在[1-3]区间内继续找合适的解。
代码如下:
#include<iostream>
using namespace std;
int n, m;
int sum(int &mid)
{
int tmp = mid;
int total = tmp;
for (int i = 0; i < n -1; ++i)
{
tmp = (tmp + 1) / 2;
total += tmp;
}
return total;
}
int fun()
{
int l = 1;
int r = m;
while (l != r)
{
int mid = (l + r + 1) / 2;
int bool_int = sum(mid);
if (bool_int == m)
{
return mid;
}
else if (bool_int < m)
{
l = mid;
}
else
{
r = mid - 1;
}
}
return r;
}
int main()
{
cin >> n >> m;
cout << fun() << endl;
return 0;
}
结果: