• P1582 倒水


    P1582 倒水

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

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

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

    输入输出格式
    输入格式:
    一行两个正整数, (N,K( 1le Nle 2 imes 10^9,Kle 1000))

    输出格式:
    一个非负整数,表示最少需要买多少新瓶子。

    Solution

    一眼看出是二进制,进位则可以丢一个瓶子, 然后就不会了QAQ
    然后我们开始试着写二进制数
    用一点点贪心: 位数越低, 需要买的瓶子越少
    所以我们看最低位代表多少瓶子, (lowbit) 凑一下
    然后呢就又发现二进制里 (1) 的数即是目前能凑出的最少瓶子数(因为前文提到的进位)
    所以补充一下不用 (bitset) 的查一个二进制数有多少个 (1) 的方法
    还是用 (lowbit) 每次louB后把最后一个 (1) 消掉即可

    int cnt(int n){int ans = 0;while(n)n -= lowbit(n), ans++;return ans;}
    

    凑瓶子就直接相加即可(相加就进位了)

    Code

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #include<bitset>
    typedef long long LL;
    using namespace std;
    int RD(){
        int out = 0,flag = 1;char c = getchar();
        while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
        while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
        return flag * out;
        }
    #define lowbit(i) (i) & (-i)
    int num, k, ans;
    int cnt(int n){int ans = 0;while(n)n -= lowbit(n), ans++;return ans;}
    int main(){
    	num = RD(), k = RD();
    	while(cnt(num) > k){ans += lowbit(num), num += lowbit(num);}
    	printf("%d
    ", ans);
    	return 0;
    	}
    
  • 相关阅读:
    Laravel 中使用支付宝、银联支付、微信支付进行支付
    C# 文件读写系列三
    C# 文件读写系列二
    C# Encoding
    C# 文件操作系列一
    Unity 依赖注入
    控制反转和依赖注入模式
    Aop学习笔记系列一
    C# lambda表达式
    C# 委托基础
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9520839.html
Copyright © 2020-2023  润新知