• 【题解】 Test 买水的ACX(套路)


    题目描述:

    ACX××信竞组学会信息竞赛,但是他的同学都很,于是要他去买水,结果来到某个买水的商店(奇奇怪怪的商店)。

    一天,ACX买了 个容量可以认为是无限大的瓶子,初始时每个瓶子里有 升水。

    ACX发现瓶子实在太多了,于是他决定 保留不超过 个瓶子。每次他选择两个当前含水量相同的瓶子合并,把一个瓶子的水全部倒进另一个瓶,然后把空瓶丢弃(不能丢弃有水的瓶子)

    显然在某些情况下ACX无法达到目标,比如 N=3,K=1.此时ACX会重新买一些新的瓶子(新瓶子容量无限,开始时有 升水),以达到目标。现

    ACX想知道,最少需要买多少新瓶子才能达到目标呢?

    读入格式:

    一行 两个正整数 N,K(1<=N<=10^9 ,K<=1000)

    输出格式:

    一个非负整数,表示最少需要买多少新瓶子。

    样例输入:

    3 1

    样例输出:

    1

     

    Solution:

    将瓶子中水的体积转换成二进制,如1升可写成0000001,同理两升就是0000010。

    题目合并的一定是相同的体积合并,所以容积一定是二的次方倍,这时候我们可以发现,二进制数上的1就可以是一个瓶子,这时候我们就可以将题目转换成加数(数就是多加了几瓶水),如样例:11 加一变成 100 就只有一个瓶子了。

    所以题目就可以变成每次加x,使这个数二进制时位上的1的个数小于k

    为了方便我们每次就加上最后一位上表示的二进制数如10010(2)时,就加10(2),使最后位置上的1进位从而减少1的个数。

    这个题目需要感性理解下吧,理解代码了还是不难的。就是一道套路题~

     

    Code:

     1 //It is coded by Ning_Mew on 11.1 :)
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<cstdlib>
     8 using namespace std;
     9 int n,k;
    10 int need=0;
    11 int a[10000+10];
    12 int num(int s){
    13   int numb=0;
    14   while(s){numb++;s=s-(s&(-s));}
    15   return numb;
    16 }
    17 int main(){
    18   freopen("water.in","r",stdin);
    19   freopen("water.out","w",stdout);
    20   scanf("%d%d",&n,&k);
    21   while(num(n)>k){
    22     need+=(n&(-n));
    23     n+=(n&(-n));
    24   }
    25   printf("%d
    ",need);
    26   return 0;
    27 }

     

  • 相关阅读:
    Nginx负载均衡配置实例详解
    Tomcat服务器
    如何设计安全的用户登录功能
    Tomcat 配置用户认证服务供C#客户端调用
    DataWindow值获取
    弹出上下文菜单
    DataWindow快速从Grid格式转为Freefrom
    postEvent() @ triggerEvent
    日期赋值为: 0000:00:00
    截取字符串
  • 原文地址:https://www.cnblogs.com/Ning-Mew/p/8488707.html
Copyright © 2020-2023  润新知