【題解】LFYZNoip前水題賽 T6
垃圾出題人們在30分鐘內完成了討論,出題,命題,造資料,跑std的所有環節
luv的化學競賽題
題目背景
luv_letters 在肝化學競賽題,他的夢想是混個省一,但是遺憾的是他今年的省二莫名消失了。
題目描述
話說societyniu比較欠扁,他嘲諷luv_letters的省二他都能拿,luv_letters當然不服2333.於是打算搞幾份卷子來考考他。
luv_letters有n種化競卷子,第i種卷子有ai道題。但是societyniu寫了太多題他又會不爽(其實是怕輸了
於是他規定他只能做K份卷子,並且為了公平起見,K份卷子被寫的題數都必須是相同的,societyniu規定這個題數就是這K份卷子的題數的最大公約數。
為什麼是最大公約數呢?因為他覺得題數是GCD的話他才會變成GG 的clevel donkey。
之前說了,societyniu熱愛理科 因此他希望K種卷子的題數和最大。你能告訴他他最後總共會做多少題麼?
輸入輸出格式
輸入格式:第一行兩個正整數n,k。 第二行n個正整數,表示每份卷子的題數。
輸出格式:輸出一個正整數表示societyniu會做多少題。
輸入輸出樣例
輸入樣例#1:3 1 1 2 3輸出樣例#1:
3
說明
對於30%的資料,保證k≤n≤20。
對於50%的資料,保證輸入中所有數小於5000。
對於100%的資料,保證輸入中所有數小於500000,k≤n。
比賽連結:https://www.luogu.org/problemnew/show/T56342
好吧,這是我出的一道巨水的題
很顯然:
題目就相當於問n個數裡面選出k個的最大公約數最大是多少。
對於30%的資料可以直接暴搜一發。(多爽
對於50%的資料...我也不知道(笑,你們可以試試各種玄學剪枝優化qwq
對於100%的資料,先開500000大的桶存下每個數出現了幾次,
然後列舉最後的答案gcd,
然後再暴力列舉所有它的倍數,看出現次數是否大於等於k就可以了。
這樣做的複雜度最壞是O(n+n/2+n/3+…+n/n)=O(nlnn)的。
自行百度調和級數求和
std:
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n, k, x, m, cnt[500010]; 4 inline int qread(){ 5 register int ch=getchar(),x=0; 6 while(!isdigit(ch)) ch=getchar(); 7 while (isdigit(ch)) x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar(); 8 return x; 9 } //隨手敲快讀 10 int main(){ 11 scanf("%d%d", &n, &k); 12 while(n--){ 13 x=qread(); 14 cnt[x]++; //開桶存數出現了幾次 15 m= m<x?x:m; 16 } 17 for(int i=m,tmp;i;i--){ 18 tmp = 0; 19 for(int j=i;j<=m;j+=i){ //暴力列舉其所有倍數直接看是否大於K 20 tmp += cnt[j]; 21 } 22 if(tmp>=k){ 23 printf("%lld\n",(long long)i*k); 24 return 0; 25 } 26 } 27 }
真的挺水的
也可以百度K-GCD