1. 程式人生 > >[luogu4571 JSOI2009] 瓶子和燃料 (數論)

[luogu4571 JSOI2009] 瓶子和燃料 (數論)

傳送門

Solution

題目說的很迷,但可以發現兩個瓶子互相倒最少是容積的gcd
那麼題目就轉化為求其中選k個瓶子gcd的最大值,這個可以分解因數,列舉因數得到

Code

//By Menteur_Hxy
#include <map>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Re register
#define Fo(i,a,b) for(Re int i=(a),_=(b);i<=_;i++)
#define Ro(i,a,b) for(Re int i=(b),_=(a);i>=_;i--)
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin)),p1==p2?EOF:*p1++)
using namespace std;
typedef long long LL;

char buf[1<<21],*p1,*p2;
inline int read() {
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
    while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}

const int MAXN=1010,MAX=1e7;
int n,k,tot,ans;
int vis[MAX],a[MAX];
map<int,int> id;

int main() {
    n=read(),k=read();
    Fo(i,1,n) {
        int x=read(),sqr=sqrt(x);
        Fo(i,1,sqr) if(x%i==0) {
            if(!id[i]) id[i]=++tot,a[tot]=i;vis[id[i]]++;
            if(!id[x/i]) id[x/i]=++tot,a[tot]=x/i;vis[id[x/i]]++;
        }
    }
    Fo(i,1,tot) if(vis[i]>=k) ans=max(ans,a[i]);
    printf("%d",ans);
    return 0;
}