zoukankan      html  css  js  c++  java
  • 1616 最小集合 51NOD(辗转相处求最大公约数+STL)

    基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
     收藏
     关注

    A君有一个集合。

    这个集合有个神奇的性质。

    若X,Y属于该集合,那么X与Y的最大公因数也属于该集合。

    但是他忘了这个集合中原先有哪些数字。

    不过幸运的是,他记起了其中n个数字。

    当然,或许会因为过度紧张,他记起来的数字可能会重复。

    他想还原原先的集合。

    他知道这是不可能的……

    现在他想知道的是,原先这个集合中至少存在多少数。


    样例解释:

    该集合中一定存在的是{1,2,3,4,6}

    Input
    第一行一个数n(1<=n<=100000)。
    第二行n个数,ai(1<=ai<=1000000,1<=i<=n)。表示A君记起来的数字。
    输入的数字可能重复。
    Output
    输出一行表示至少存在多少种不同的数字。
    Input示例
    5
    1 3 4 6 6
    Output示例
    5
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<set>
    using namespace std;
    set<int>se;
    int n;
    int b[10000],ans;
    int gcd(int x,int y){
        return x == 0 ? y: gcd(y % x, x);
    }
    int main(){
        cin>>n;
        for(int i = 0; i < n; i++){
            cin>>b[i];
            se.insert(b[i]);
        }
        for(int i = 0; i < n; i++){
            for(int j = i+1; j < n; j++){
                se.insert(gcd( b[i] , b[j] ));
            }
        }
        cout<<se.size();
    }

      错误思路:输入数b,用STL中的set集合存储,因为set集合不含有相同的元素,所以实现了去重;

    然后两两比较找GCD,存入集合se中,最后se的长度就是所存数子个数,但由于数据范围极大,所以上面的做法不能过全部数据点;

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #define fo(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    int read(int &n)
    {
        char ch=' ';int q=0,w=1;
        for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
        if(ch=='-')w=-1,ch=getchar();
        for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
    }
    int m,n,ans;
    bool a[1000006];
    int gcd(int x,int y){return y?gcd(y,x%y):x;}
    int main()
    {
        int q,w=0;
        read(n);
        fo(i,1,n)a[read(q)]=1,m=max(m,q),w=gcd(q,w);
        if(w==1)ans=1;
        fo(i,2,m)
        {
            q=w=0;
            fo(j,1,m/i)if(a[j*i])q=gcd(j,q),w++;
            if((q==1&&w-1)||a[i])ans++;
        }
        printf("%d
    ",ans);
        return 0;
    }

      正确思路:

      很简单,只要枚举每个数,再枚举它的倍数来判断它在不在集合中, 
    判断只要看看输入的数中,所以是它的倍数的数的gcd是不是1即可, 
    我们知道:ni=1ni=nlog2(n);

    复杂度:O(mlog2(m)2)m<=106

    题目地址:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1616

    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    [转贴]Asp.Net[C#]在线压缩解压
    [转载]如何用C#语言构造蜘蛛程序
    [转载].net 集合类初步认识
    试用随笔
    安装中文VS2008 SP1 和.NETFRAMEWORK 3.5SP1后智能提示是英文的解决办法
    关于IE提示“Internet Explorer无法打开站点,已终止操作”的解决办法
    linux每天建立一个以当天日期命名的文件夹
    linux常用装机命令
    linux安装oracle客户端
    批量分发文件
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/6053101.html
Copyright © 2011-2022 走看看