1. 程式人生 > >【題解】LFYZNoip前水題賽 T6

【題解】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