• P1582 倒水 (二进制)


    题目描述

    一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水。接着~~CC发现瓶子实在太多了,于是他决定保留不超过K个瓶子。每次他选择两个当前含水量相同的瓶子,把一个瓶子的水全部倒进另一个里,然后把空瓶丢弃。(不能丢弃有水的瓶子)

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

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

    输入输出格式

    输入格式:

    一行两个正整数, N,K( 1le Nle 2 imes 10^9,Kle 10001N2×109,K1000 )。 

    输出格式: 

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

    输入输出样例

    输入样例#1: 
    3 1
    
    输出样例#1: 
    1
    
    输入样例#2: 
    13 2
    输出样例#2: 
    3
    输入样例#3: 
    1000000 5
    输出样例#3:
    15808

    Solution

    二进制水题一道.

    因为只有当有两个相同的水瓶时才可以合并;

    所以可以很快推出一条性质:

    每个合并出来的水瓶最终水量必为 2 的 n 次方.

    然后也就是说,把当前这个数转化成二进制,它共有多少位是 1 , 也就是它可以合并出来的水瓶.

    因为只能加,所以我们就一步一步把这个数字跳为恰有 k 个1的最小值即可.

    关于取一的个数;

    树状数组引用过一个 x&(-x) 便能取出末尾的1.

    每次取完减去即可,直到为0.

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int n,k,ans;
    int pal(int x)
    {
        int num=0;
        while(x)
        {
            num++;
            x-=x&-x;
        } 
        return num;
    }
    int main(){
        scanf("%d%d",&n,&k);
        while(pal(n)>k) 
        ans+=n&-n,n+=n&-n;
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    JQuery中的回调对象
    CSS中的视觉格式化模型
    css中的选择器
    浅谈css中的position
    python-24: re 模块 之二 re方法及反斜杠
    python-23 xml.etree.ElementTree模块
    python-22 eval json pickle shelve 之间差别
    python-21 os 模块
    python-18: datetime 模块
    python-16: time 模块 之二
  • 原文地址:https://www.cnblogs.com/Kv-Stalin/p/9069593.html
Copyright © 2020-2023  润新知