• 洛谷 P1414 又是毕业季II(最大公约数)


    题目链接

    https://www.luogu.org/problemnew/show/P1414

    题目背景

    “叮铃铃铃”,随着高考最后一科结考铃声的敲响,三年青春时光顿时凝固于此刻。毕业的欣喜怎敌那离别的不舍,憧憬着未来仍毋忘逝去的歌。1000多个日夜的欢笑和泪水,全凝聚在毕业晚会上,相信,这一定是一生最难忘的时刻!

    题目描述

    彩排了一次,老师不太满意。当然啦,取每位同学的号数来找最大公约数显然不太合理。于是老师给每位同学评了一个能力值。于是现在问题变为,从n个学生中挑出k个人使得他们的默契程度(即能力值的最大公约数)最大。但因为节目太多了,而且每个节目需要的人数又不知道。老师想要知道所有情况下能达到的最大默契程度是多少。这下子更麻烦了,还是交给你吧~

    PS:一个数的最大公约数即本身。

    输入输出格式

    输入格式:

    第一行一个正整数n。

    第二行为n个空格隔开的正整数,表示每个学生的能力值。

    输出格式:

    总共n行,第i行为k=i情况下的最大默契程度。

    输入输出样例

    输入样例#1:
    4
    1 2 3 4
    
    输出样例#1:
    4
    2
    1
    1
    

    说明

    【数据范围】

    记输入数据中能力值的最大值为inf。

    对于20%的数据,n<=5,inf<=1000

    对于另30%的数据,n<=100,inf<=10

    对于100%的数据,n<=10000,inf<=1e6

    解题思路

    这个题就是求从n个数中选1...n个数时的最大公因数。

    首先,数据范围较大,暴力枚举肯定要炸,所以我们需要换一种思路。

    我们用vis[i]存下i出现的次数,用num[i]表示以i为因数的数(i的倍数)一共有多少个,用ans[i]表示选i个数的最大公因数。 

    所以我们枚举每一个因数,记录下这一个因数在这n个数中有多少个倍数,用num记录。

    然后枚举每一个因数,根据num得知他是多少个数的因数,然后不断更新答案。

    因为枚举因数时是从小到大枚举的,所以ans的每一次更新的值都会比原来的数值大,保证了答案的正确性。

    具体过程请看代码(内有具体思路)。

     
     1 #include<iostream>
     2 #include<cmath>
     3 using namespace std;                        //vis[i]表示 i出现的次数
     4 int n,vis[1000005],num[1000005],ans[10005]; //num[i]表示以i为因数的数(i的倍数)一共有多少个,ans[i]表示选i个数的最大公因数  
     5 int maxx;                                     //maxx存的是n个正整数的最大值。这样节约了时间 
     6 int main()
     7 {
     8 cin>>n;
     9 for(int i=1;i<=n;i++){
    10     int in;
    11     cin>>in;
    12     vis[in]++;
    13     maxx=max(in,maxx);                        //更新最大值 
    14 }
    15 for(int i=1;i<=maxx;i++)                    //i枚举的是因数 
    16 for(int j=i;j<=maxx;j+=i){                    //j枚举的是i的倍数 
    17     num[i]+=vis[j];                            //i的倍数加上j这个数出现的次数 
    18 }
    19 for(int i=1;i<=maxx;i++)                    //i枚举的是因数 
    20 for(int j=1;j<=num[i];j++){                    //j枚举的是这个因数的倍数的个数 
    21     ans[j]=i;                                //选j个数的最大公因数有可能是i(但不一定是,至少到目前为止是) 
    22 }
    23 for(int i=1;i<=n;i++) cout<<ans[i]<<endl;    //输出 
    24 return 0;
    25 }
    AC代码(附解析)
  • 相关阅读:
    ORACLE创建数据库时无法创建目录
    KindEditor:Ajax提交表单时获取不到HTML内容
    mysql重置root密码
    假设检验-单样本检验
    推论统计分析-如何避免偏见和抽样分布
    推论统计分析1
    共享单车数据分析
    Kaggle泰坦尼克号生存情况预测
    R-长尾词练习
    R期望
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/10474023.html
Copyright © 2020-2023  润新知