1. 程式人生 > >BZOJ-2257: [Jsoi2009]瓶子和燃料 (中國剩余定理)

BZOJ-2257: [Jsoi2009]瓶子和燃料 (中國剩余定理)

spa pan read getch .com 兩個 sin 飛船 href

2257: [Jsoi2009]瓶子和燃料

Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 1583 Solved: 965
[Submit][Status][Discuss]

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

HINT

選擇第2 個瓶子和第 個瓶子,火星人被迫會給出4 體積的容量。

Source

嘛……laj也忘了叫什麽定理了 好像是中國剩余定理叭qwq

首先可以得出兩個瓶子倒來倒去最後剩下的一定是他們的gcd,然後這樣就相當於求k個數的最大gcd為多少qwq誒這題怎麽這麽熟悉qwq

 1 #include "bits/stdc++.h
" 2 using namespace std; 3 typedef long long LL; 4 const int MAX=1e6+5; 5 int n,m,an; 6 int p[MAX],t[MAX]; 7 inline int read(){ 8 int an=0,x=1;char c=getchar(); 9 while (c<0 || c>9) {if (c==-) x=-1;c=getchar();} 10 while (c>=0 && c<=9) {an=(an<<3)+(an<<1
)+c-0;c=getchar();} 11 return an*x; 12 } 13 void calc(int x){ 14 int i,j; 15 for (i=1;i*i<x;i++) 16 if (x%i==0) 17 p[++p[0]]=i,p[++p[0]]=x/i; 18 if (i*i==x) p[++p[0]]=i; 19 } 20 bool cmp(int x,int y){return x>y;} 21 int main(){ 22 freopen ("bottle.in","r",stdin);freopen ("bottle.out","w",stdout); 23 int i,j,x; 24 n=read(),m=read(); 25 for (i=1;i<=n;i++) x=read(),calc(x); 26 sort(p+1,p+p[0]+1,cmp); 27 for (i=1;i<=p[0];i++) 28 if (p[i]==p[i-1]) an++; 29 else{ 30 if (an>=m) return printf("%d",p[i-1]),0; 31 an=1; 32 } 33 }

BZOJ-2257: [Jsoi2009]瓶子和燃料 (中國剩余定理)