杯子
題目
題目描述 小明買了N個容積可以是無窮大的杯子,剛開始的時候每個杯子里有1升水, 接著小明發現杯子實在太多了,于是他決定保留不超過K個杯子。每次他選擇兩 個當前含水量相等的杯子,把一個杯子的水全部倒進另一個里,然后把空瓶丟棄。(不能丟棄有水的杯子) 顯然在有些情況下小明無法達到他的目標,比如N=3,K=1。此時小明會重
新買一些新的杯子(新杯子容積無限,開始時有1升水),以達到目標。 現在小明想知道,最少需要買多少個新杯子才能達到目標呢? 輸入 一行兩個正整數,N,K(1≤N≤1000000000,K≤1000)。 輸出 一個非負整數,表示最少需要買多少新杯子。 樣例輸入 1000000 5 樣例輸出 15808 提示 【數據范圍】
對于50%的數據,N≤10000000; 對于100%的數據如題目。
分析
聲明:由于我實在是太蔡了,所以考試的時候根本沒想到正解……
后來推樣例的時候,我才發現杯子內的水從1到2再到4的過程很像2進制運算,且本題數據極大,O(n)都不行,所以CJX告訴我,要么是貪心,要么是數論,要么是貪心+數論。
所以每一個杯子里的水量都是2x(x為非負整數),進而我們知道每2y個水量為1杯子可以變成1個杯子(這一個杯子里的水量為2y)。
為了使新添的杯子數量最少,所以每次都要讓y最大,故使用貪心。
代碼
#include<bits/stdc++.h> using namespace std; long long n,k,a,x=1,sum=1; int main() {scanf("%lld%lld",&n,&k);if(k>=n){putchar('0');exit(0);}while(sum<=n) sum<<=1a=sum>>1;while(x<k){while(a>n) a>>=1;x++;n-=a;}sum=1;while(sum<=n) sum<<=1;//計算需要用幾個水量為1杯子才能將剩下的所有杯子變成一個杯子。 printf("%lld",sum-n);return 0; }轉載于:https://www.cnblogs.com/DARTH-VADER-EMPIRE/p/11363039.html
總結
- 上一篇: 获取控件坐标位置一直是0
- 下一篇: 玩具