分草稿纸(二分法)

链接: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;
}

 
 
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值