1. 程式人生 > >BZOJ 2257: [Jsoi2009]瓶子和燃料

BZOJ 2257: [Jsoi2009]瓶子和燃料

tput turn desc using != 刻度 分解因數 color sqrt

Description

jyy就一直想著盡快回地球,可惜他飛船的燃料不夠了。
有一天他又去向火星人要燃料,這次火星人答應了,要jyy用飛船上的瓶子來換。jyy
的飛船上共有 N個瓶子(1<=N<=1000) ,經過協商,火星人只要其中的K 個 。 jyy
將 K個瓶子交給火星人之後,火星人用它們裝一些燃料給 jyy。所有的瓶子都沒有刻度,只
在瓶口標註了容量,第i個瓶子的容量為Vi(Vi 為整數,並且滿足1<=Vi<=1000000000 ) 。
火星人比較吝嗇,他們並不會把所有的瓶子都裝滿燃料。他們拿到瓶子後,會跑到燃料
庫裏鼓搗一通,弄出一小點燃料來交差。jyy當然知道他們會來這一手,於是事先了解了火


星人鼓搗的具體內容。火星人在燃料庫裏只會做如下的3種操作:1、將某個瓶子裝滿燃料;
2、將某個瓶子中的燃料全部倒回燃料庫;3、將燃料從瓶子a倒向瓶子b,直到瓶子b滿
或者瓶子a空。燃料傾倒過程中的損耗可以忽略。火星人拿出的燃料,當然是這些操作能
得到的最小正體積。
jyy知道,對於不同的瓶子組合,火星人可能會被迫給出不同體積的燃料。jyy希望找
到最優的瓶子組合,使得火星人給出盡量多的燃料。

Input

第1行:2個整數N,K,
第2..N 行:每行1個整數,第i+1 行的整數為Vi

Output

僅1行,一個整數,表示火星人給出燃料的最大值。

Sample Input

3 2
3
4
4

Sample Output

4

怎麽感覺題目這麽熟悉,倒水問題……,但是好像不一樣

k個瓶子裝任意多的燃料,但是得符合那是三條規定,我們得把這個問題轉化一下,

如果二話不說直接爆搜的話,很大可能 A 不了這道題

我們簡單分析可以看出,答案是選擇瓶子容積的最大公約數,不要問我怎麽看出來的……因為我也不知道

思路的話就是 分解因數

#include<iostream>
#include<cstdio>
#include<cmath>
#include
<algorithm> #define mod 100000 using namespace std; int s[20000000]; int ans,n,k; int decom(int sum) { for(int i=1;i<=sqrt(sum);++i) if(!(sum%i)) { s[++ans]=i; if(i!=sum/i) s[++ans]=sum/i; } } int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;++i) { int num; cin>>num; decom(num); } sort(s+1,s+ans); int lianxu=1,m=1; for(int i=ans;i>0;--i) { if(s[i+1]==s[i]) lianxu++; else { if(lianxu>=k) { printf("%d",s[i+1]); return 0; } lianxu=1; } } }

BZOJ 2257: [Jsoi2009]瓶子和燃料