來水一發水題。。
題目鏈結。
正解開始:
首先,我們根據題意,可以得知這是乙個有關二進位制的題目;
具體什麼關係,怎麼做,我們來具體分析:
對於每個n,我們嘗試將其二進位制分解,也就是100101之類的形式
根據瓶子合併的特性,我們可以判定最後每乙個瓶子內的水都可以表示成2^i的形式
感性理解:對於每乙個數字上為1的地方,自然,他可以經過多次合併(瓶子加水)來合成,因為每個瓶子內的水都可以表示成2^i的形式,也就對應著n二進位制分解上的乙個1.
說白了就是從開始的那一堆瓶子裡面進行合成,最後在不加瓶子的情況下,必定會合成為n的二進位制分解的形式,其中1的個數為瓶子剩餘的個數。
那麼我們求n的二進位制分解中有多少個1,如果1的個數比k小了,說明經過一系列令人窒息的操作後我們在不加瓶子的情況下能夠最後剩餘的瓶子個數。如果比k要大的話,我們考慮加瓶子:
舉個例子:18 用二進位制表示的話就是:1010
其中剩餘兩個瓶子,其中內的水量分別是16l,2l。如果我們要求k=1,也就是只剩下1個瓶子的話,那麼我們貪心的考慮,自然買的瓶子量越少越好,也就是從二進位制位右邊開始,檢測1,這時檢測到了內含有2l水的瓶子,要想合併,自然要另外找新瓶子並合併成和當前瓶子容量一致的新瓶子,也就是我們還需要1個2l水的瓶子,那麼自然的,我們需要兩瓶新水,把2累加到答案ans上。
10010+10=10100;
10100+100=11000;
11000+1000=100000;
這時候只剩下1瓶內含有32公升水的瓶子。符合k=1的要求
那麼答案就是10+100+1000=1110(二進位制)=14公升水=14個新瓶子。
思路講解完畢,**如下:
#include#include#include
using
namespace
std;
intread()
intn,k,ans;
int lowbit(int
x)int find1(int
n)
return
num;
}int
main()
printf("%d
",ans);
}
完結
P1582 倒水(思維)
思路 首先如果乙個數等於2的n次方,那麼合併後一定是1個瓶子。而2的n次方中1的個數也是1個,13的二進位制1 1 0 1,二進位制1的個數3個,剛好13合併後是3個瓶子。我們可以得到乙個數二進位制1的個數就是這個數合併後的瓶子個數。我們在學樹狀陣列時有乙個lowbit函式 x x 就是取最後一位1...
洛谷P1582 倒水
一天,cc買了n個容量可以認為是無限大的瓶子,開始時每個瓶子裡有1公升水。接著 cc發現瓶子實在太多了,於是他決定保留不超過k個瓶子。每次他選擇兩個當前含水量相同的瓶子,把乙個瓶子的水全部倒進另乙個裡,然後把空瓶丟棄。不能丟棄有水的瓶子 顯然在某些情況下cc無法達到目標,比如n 3,k 1。此時cc...
洛谷P1582 倒水
一天,cc買了n個容量可以認為是無限大的瓶子,開始時每個瓶子裡有1公升水。接著 cc發現瓶子實在太多了,於是他決定保留不超過k個瓶子。每次他選擇兩個當前含水量相同的瓶子,把乙個瓶子的水全部倒進另乙個裡,然後把空瓶丟棄。不能丟棄有水的瓶子 顯然在某些情況下cc無法達到目標,比如n 3,k 1。此時cc...