倒水 二進位制 lowbit函式

2021-08-21 20:21:03 字數 1512 閱讀 3620

p1582 倒水,

傳送門

題目描述

一天,cc買了n個容量可以認為是無限大的瓶子,開始時每個瓶子裡有1公升水。接著~~cc發現瓶子實在太多了,於是他決定保留不超過k個瓶子。每次他選擇兩個當前含水量相同的瓶子,把乙個瓶子的水全部倒進另乙個裡,然後把空瓶丟棄。(不能丟棄有水的瓶子)

顯然在某些情況下cc無法達到目標,比如n=3,k=1。此時cc會重新買一些新的瓶子(新瓶子容量無限,開始時有1公升水),以到達目標。

現在cc想知道,最少需要買多少新瓶子才能達到目標呢?

輸入輸出格式

輸入格式:

一行兩個正整數, n,k( 1\le n\le 2\times 10^9,k\le 10001≤n≤2×10

9,k≤1000 )。

輸出格式:

乙個非負整數,表示最少需要買多少新瓶子。

輸入輸出樣例

輸入樣例#1:

3 1

輸出樣例#1:

1

輸入樣例#2:

13 2

輸出樣例#2:

3

輸入樣例#3:

1000000 5

輸出樣例#3:

15808

這道題目不得不說是非常巧妙的,不了解二進位制的人大概會寫的很複雜而且還不一定寫的出來,而使用二進位制,就變得十分簡單了。不得不說二進位制是非常神奇的東西

分析題意,是要求至少需要多少個1公升的瓶子才能兩兩合起來最後瓶子數不超過k。如果暴力求解的話,恐怕列舉方式很複雜。

但是我們可以想象,對於一直數量的瓶子,比如13,它的二進位制數是8+4+1,即1101,那麼它加乙個瓶子就是1110,至少瓶子數不會增多,那麼對於現在的14,1110,需要加幾個瓶子,會使得合起來之後的瓶子數會減少或不增多呢?很容易知道是2,合起來就是10000,如果只加乙個,那就變成1111了,還多了乙個。我們可以觀察發現,它的瓶子數要變少,就需要至少加從右邊數直到第乙個1停止的那個數的數量。而學習過樹狀陣列的同學(或者其他lowbit()函式相關演算法),應該就明白了。

沒錯,上面一段的關鍵,就是引出lowbit函式。n & -n.

對乙個數的二進位制表示上,有幾位是1,就代表了有幾個瓶子。所以我們可以while迴圈,直到該數的1的位數<=k,不然就一直加n & -n, 調整它的位數, 直到滿足退出迴圈的條件。

所以**也是非常非常簡潔的。

#include 

using

namespace

std;

int getone(long

long n)

return cnt;

}int main()

P1582 倒水(二進位制)

p1582 倒水 評測方式 雲端評測 標籤難度 普及 提高 時空限制 1000ms 128mb 最新討論 推薦的相關題目 題目描述 一天,cc買了n個容量可以認為是無限大的瓶子,開始時每個瓶子裡有1公升水。接著 cc發現瓶子實在太多了,於是他決定保留不超過k個瓶子。每次他選擇兩個當前含水量相同的瓶子...

P1582 倒水 二進位制

一天,cc買了n個容量可以認為是無限大的瓶子,開始時每個瓶子裡有1公升水。接著 cc發現瓶子實在太多了,於是他決定保留不超過k個瓶子。每次他選擇兩個當前含水量相同的瓶子,把乙個瓶子的水全部倒進另乙個裡,然後把空瓶丟棄。不能丟棄有水的瓶子 顯然在某些情況下cc無法達到目標,比如n 3,k 1。此時cc...

二進位制 二進位制起源

現代通訊技術的基礎是二進位制編碼。早在1865年麥克斯韋總結出麥克斯韋方程組之前,美國人摩斯 morse 於1837年發明了摩斯電碼和有線電報。有線電報的出現,具有劃時代的意義 它讓人類獲得了一種全新的資訊傳遞方式,這種方式 看不見 摸不著 聽不到 完全不同於以往的信件 旗語 號角 烽火,這也是二進...