zoukankan      html  css  js  c++  java
  • POJ 3904 Sky Code

    题目地址: http://poj.org/problem?id=3904


    题意:给出n个数,问找出4个数满足4个数最大公约数为1,最多有多少组。
    思路:容斥原理,遍历每个数的素因子,奇数个加偶数个减,然后C(n,4)-sum。


    //求得是n个数中,有多少组(a,b,c,d)的公约数为1,值得注意的是这四个数不一定两两互质。  
    //所以我们从它的反面考虑,先求出公约数不为1的个数。  
    //思路:把每个数素数分解,记录不重复素因子所能组成的因子,把这些因子的总数统计,并且统计每个因子是由多少个素因子组成  
    //如这n个数中含2的个数为a,含3的个数为b,含6的个数为c,那么公约数大于1的总数为p=c(a,4)+c(b,4)-c(c,4),总的个数为c(n,4)  
    //用c(n,4)-p即为所求


    AC代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <list>
    #include <deque>
    #include <queue>
    #include <iterator>
    #include <stack>
    #include <map>
    #include <set>
    #include <algorithm>
    #include <cctype>
    #include <cfloat>
    using namespace std;
    
    typedef __int64 LL;
    const int N=10005;
    const LL II=1000000007;
    const int INF=0x3f3f3f3f;
    const double PI=acos(-1.0);
    
    LL n,m,pri[N],num[N],co[N],p[N];
    
    void init()
    {
        memset(p,0,sizeof(p));
        memset(num,0,sizeof(num));
        for(LL i=4;i<N;i++)//p[i]表示总共有多少种方法
            p[i]=i*(i-1)*(i-2)*(i-3)/24;
    }
    
    LL prime(LL x)
    {
        LL i,j,numi=0;
        for(i=2;i*i<=x;i++)
            if(x%i==0)
            {
                pri[numi++]=i;
                while(x%i==0)
                    x/=i;
            }
        if(x>1)
            pri[numi++]=x;
        return numi;
    }
    
    void dfs(LL k)
    {
        LL i,j,t,numi;
        numi=prime(k);
        LL sum=0;
        for(i=1;i<(1<<numi);i++)
        {
            LL temp=1,k=0;
            for(j=0;j<numi;j++)
                if(i&(1<<j))
                {   temp*=pri[j];   k++;    }
            co[temp]++;//记录当前因子的个数
            num[temp]=k;//记录当前因子是由多少个素因子组成
        }
    }
    
    int main()
    {
        LL i,j,T;
        init();
        while(~scanf("%I64d",&n))
        {
            memset(co,0,sizeof(co));
            for(i=1;i<=n;i++)
            {
                scanf("%I64d",&m);
                dfs(m);
            }
            LL sum=0;
            for(i=0;i<N;i++)
            {
                if(!co[i])   continue;
                if(num[i]&1)    sum+=p[co[i]];
                else    sum-=p[co[i]];
            }
            printf("%I64d
    ",p[n]-sum);
        }
        return 0;
    }
    


  • 相关阅读:
    限定类型后undefined变null
    学习进度条(第一周)
    记账本开发小计(三)
    记账本开发小计(四)
    记账本开发小计(五)
    个人作业1数组
    记账本开发小计(二)
    记账本开发小计(七)
    记账本开发小计(六)
    软件工程概论第一次课堂测试(实发项目的开发)总结
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3193938.html
Copyright © 2011-2022 走看看