• CF #552(div3)G 最小lcm


    题目链接:http://codeforces.com/contest/1154/problem/G

    题意:lcm是最小公倍数,本题就是给你一个数组(可能会重复),要求你判断出那两个数的最小公倍数最小,并输出这两个数的下标

    分析:首先想重复,因为重复的话非常好整,最小公倍数就是它自己,所以我们可以先处理一遍,把出现过的重复的数最小的先设为答案(ans)。

    另外,记得初始化ans,这里有个坑,记得不要初始化为inf,因为最小公倍数是会爆int的,这点要注意。

    然后再开始从1-ans遍历,对于每个数,都不断加倍,来寻找答案,遍历完后输出答案。

    注意输出是下标。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int inf=0x3f3f3f3f;//这个数是1e9数量级的,且可以用memset函数 
    const int maxn=1e7+7;
    const double pi=acos(-1);
    const int mod=1e9+7;
    int idx[maxn];//idx[x]存的是数值x的下标 
    int main(){
        int n;scanf("%d",&n);
        int t1=0,t2=0,x;ll ans=1e14;
        for(int i=1;i<=n;i++){
            scanf("%d",&x);
            if(idx[x]){
                if(ans>x) 
                t1=idx[x],t2=i,ans=x;
            }
            else idx[x]=i;
        }
        for(int i=1;i<=maxn;i++){//因为ans是一直在动态变化的,所以这里终止条件我们设为maxn 
            if(i>=ans) break;
            int s1=0,s2=0;//s1,s2分别记录接下来循环存在的第一个数的值和下标 
            for(int j=i;j<=maxn;j+=i){
                if(!idx[j]) continue;
                if(!s1) s1=j,s2=idx[j]; 
                else{
                    if(ans>1ll*j*s1/i){//最小公倍数=两数乘积/最大公因数     这里可能会溢出,记得转化 
                        ans=1ll*j*s1/i;
                        t1=s2,t2=idx[j];
                        break;
                    }
                }
            }
        }
        if(t1>t2) swap(t1,t2);
        cout<<t1<<" "<<t2<<endl;
        return 0;
    }
  • 相关阅读:
    postman中 form-data、x-www-form-urlencoded、raw、binary的区别
    常见的http response
    ==容易错误的例子
    点击panel滚动条滚动到底部
    fabric实现文本聚焦、可编辑
    JSON.parse()和JSON.stringify()的使用
    centos7安装mysql
    阿里云第一次访问tomcat非常慢的解决办法
    java中的语法糖
    jvm | 基于栈的解释器执行过程
  • 原文地址:https://www.cnblogs.com/qingjiuling/p/10774236.html
Copyright © 2020-2023  润新知