链接:https://ac.nowcoder.com/acm/contest/374/H
来源:牛客网
小西小理准备做ACM题来一决胜负,由于做题途中需要演算,小西和小理一起买了一沓草稿纸,草稿纸共有m张,两人将轮流撕走一些草稿纸用来演算。由于题目有些难度,两人每次撕走的数量将不少于前一个人的一半,为了确保这一沓纸可以更经用一些(可以被撕n次,每个人撕都算一次),先撕的人第一次最多可以撕多少张?(必须要多次输入不然过不了,他这也没说要多次有点坑,咱也不敢问😥)
输入描述:
输入包括两个整数n与m,分别代表要求被撕的次数和草稿纸的数量(n<=50000,n<=m<=1000000)
输出描述:
输出包括一个整数,代表先撕的人第一次最多可以撕多少张,输出占一行
示例1
输入
3 7
输出
4
基本思想就是二分,先假设从中间分开,然后再进行测试如果从中间分的话,一共按照(“两人每次撕走的数量将不少于前一个人的一半”)的规则进行n次叠加,如果最后加起来的数量比草稿纸总数少,说明第一次撕的纸应该更多些。相反,则说明第一次撕的纸应该少一点。
以下是通过的代码:
#include "bits/stdc++.h"
typedef long long int ll;
using namespace std;
ll n,m;
ll f(ll x){
ll sum=0;
for(ll i=1;i<=n;i++){
sum+=x;
x=(x+1)>>1;
}
return sum;
}
int main()
{
while(cin>>n>>m)
{
ll mid,l=1,r=m;
while(l<=r){
mid=l+((r-l)>>1);
if(f(mid)<m)
l=mid+1;
else if(f(mid)>m)
r=mid-1;
else
{
cout<<mid<<endl;
break;
}
}
if(f(mid)!=m)
cout<<r<<endl;
}
return 0;
}