Codeforces Round #552 (Div. 3)---G:Minimum Possible LCM(枚举)

题意:

从n个数中选出2个数,使得这两个数的最小公倍数最小

分析:

LCM(a,b) = a * b / gcd(a,b);考虑枚举公因数d,假设n个数中具有因子d的数分别是x1,x2,x3,x4.....(x1 < x2 < x3 < x4 ......)

如果x1 与 x2 的最大公因数就是d,那么lcm(x1,x2) = x1*x2/d,如果x4 与 x1 的最大公因数也是d,那么x4*x1/d一定大于x1*x2/d,所以后面的就不用考虑了

如果x1 与x2 的最大公因数不是d,那么lcm(x1,x2) 一定小于x1*x2/d,即使x4 与 x1的最大公因数是d,那么x4*x1/d一定大于lcm(x1,x2),同样后面也不用考虑了

所以我们只需要得到每个d的倍数的前2项即可,时间复杂度(1e7*log(le7))

代码:

#include <bits/stdc++.h>

using namespace std;
const int maxn = 1e7+17;
int a[maxn],pos[maxn],n,v,x,y;
int main(){
    cin >> n; long long res = 1e18;
    for(int i = 1;i <= n ; ++i){
        cin >> v;
        a[v]++;
        if(a[v] > 1 && v < res){             //处理相同的数
            res = v;
            x = pos[v];
            y = i;
        }
        pos[v] = i;
    }
    for(int i = 1;i < maxn; ++i){
        int val = 0;
        for(int j = i;j < maxn; j+=i){
            if(!a[j]) continue;
            if(!val) val = j;
            else{
                long long g = __gcd(val/i,j/i);
                if(g == 1){
                    long long lcm = 1LL*j/i*val;
                    if(lcm < res){
                        res = lcm;
                        x = pos[val];
                        y = pos[j];
                    }
                }
                break;
            }
        }
    }
    if(x > y) swap(x,y);
    cout << x << " " << y << '\n';
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41157137/article/details/89353527