zoukankan      html  css  js  c++  java
  • Project Eular 632/633

    先讨论一下632

    我们先求一遍,然后容斥

    先求一遍的时候,我们对于每个数x

    如果x的因子里面带平方,那么就忽略掉,否则就在ans[x的因子个数]上加(1016/x2)的答案

    之后容斥,我们就可以求出这个答案

    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<stack>
    #include<string>
    #include<time.h>
    #include<math.h>
    #include<memory>
    #include<vector>
    #include<bitset>
    #include<fstream>
    #include<stdio.h>
    #include<utility>
    #include<sstream>
    #include<string.h>
    #include<iostream>
    #include<stdlib.h>
    #include<algorithm>
    using namespace std;
    int ans[100000005];
    int last_p[100000005];
    const long long n=100000000ll*100000000;
    long long final_ans[15];
    const int modo=1000000007;
    int c(int n,int m)
    {
        long long i;
        long long p=1;
        for (i=1;i<=n;i++)
        {
            p*=i;
        }
        for (i=1;i<=m;i++)
        {
            p/=i;
        }
        for (i=1;i<=n-m;i++)
        {
            p/=i;
        }
        return p;
    }
    const int m=100000000;
    int main()
    {
        memset(ans,0,sizeof(ans));
        int i,j;
        ans[1]=0;
        for (i=2;i<=m;i++)
        {
            if (ans[i]==-1) continue;
            if (i<=10000)
            {
                for (j=i*i;j<=m;j+=i)
                {
                    ans[j]=-1;
                    last_p[j]=i;
                }
            }
        }
        for (i=2;i<=m;i++)
        {
            if (ans[i]==0)
            {
                ans[i]=1;
            }
            else
            {
                if ((i/last_p[i])%last_p[i]==0)
                {
                    ans[i]=-10000;
                }
                else
                {
                    ans[i]=ans[i/last_p[i]]+1;
                }
            }
        }
        for (i=1;i<=m;i++)
        {
            if (ans[i]<0) continue;
            //cout<<ans[i]<<" ";
            final_ans[ans[i]]+=(n/i/i);
        }
        //cout<<endl;
        for (i=14;i>=0;i--)
        {
            int j;
            for (j=14;j>i;j--)
            {
                final_ans[i]-=final_ans[j]*c(j,i);
            }
        }
        long long p=1;
        for (i=0;i<=14;i++)
        {
            cout<<final_ans[i]<<endl;
            if (final_ans[i]!=0)
            {
                p=(long long)p*(final_ans[i]%modo)%modo;
            }
        }
        cout<<endl<<endl<<p<<endl;
        system("pause");
        return 0;
    }
    

    然后633是一个近似的过程

    由于要我们求7的,我们就求7+的

    显然我们已经不满足于1016这么小的范围,那只好扩大

    把程序改成搜索,开始爆搜

    加个剪枝还是挺快的

    质数可以少选一些,后面的不要了

    跑出最终结果需要一段时间,还要耐心等待...

    反正最后跑出来结果以后我们还可以再稍微加一加试一试对不对,我们精度4位就够,题目也只要求5位

    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<stack>
    #include<string>
    #include<time.h>
    #include<math.h>
    #include<memory>
    #include<vector>
    #include<bitset>
    #include<fstream>
    #include<stdio.h>
    #include<utility>
    #include<sstream>
    #include<string.h>
    #include<iostream>
    #include<stdlib.h>
    #include<algorithm>
    using namespace std;
    const long long m=1000000000000ll;
    int c(int n,int m)
    {
        long long i;
        long long p=1;
        for (i=1;i<=n;i++)
        {
            p*=i;
        }
        for (i=1;i<=m;i++)
        {
            p/=i;
        }
        for (i=1;i<=n-m;i++)
        {
            p/=i;
        }
        return p;
    }
    bool prime[4000005];
    int p[500005];
    int cnt=0;
    double ans[15];
    double calc(long long x,int y,int c=0)
    {
        if (x>m)
        {
            return 0;
        }
        if (y==0)
        {
            return (long long)((double)m*m/x/x);
        }
        int i;
        double sum=0;
        for (i=c;i<cnt;i++)
        {
            double k=calc(x*p[i],y-1,i+1);
            if (k==0)
            {
                return sum;
            }
            sum+=k;
        }
        return sum;
    }
    int main()
    {
        memset(prime,true,sizeof(prime));
        int i,j;
        ans[1]=0;
        for (i=2;i<=10000;i++)
        {
            if (prime[i])
            {
                for (j=i*i;j<=4000000;j+=i)
                {
                    prime[j]=false;
                }
            }
        }
        for (i=2;i<=4000000;i++)
        {
            if (prime[i])
            {
                p[cnt++]=i;
            }
        }
        ans[10]=max(0.0,calc(1,10));
        ans[9]=max(0.0,calc(1,9));
        ans[8]=calc(1,8);
        ans[7]=calc(1,7);
        ans[9]-=c(10,9)*ans[10];
        ans[8]-=c(10,8)*ans[10];
        ans[7]-=c(10,7)*ans[10];
        ans[8]-=c(9,8)*ans[9];
        ans[7]-=c(9,7)*ans[9];
        ans[7]-=c(8,7)*ans[8];
        cout<<ans[7]<<endl;
        system("pause");
        return 0;
    }
    
  • 相关阅读:
    linux常用命令整理
    总结五大常用算法!
    python数组(列表、元组及字典)
    网络编程---笔记1
    python3与python2的区别 记录一波
    Python学习week3-python数据结构介绍与列表
    Python学习week2-python介绍与pyenv安装
    Python学习week1-linux文件系统与IO重定向
    Python学习week1-计算机基础
    css3文本多行省略
  • 原文地址:https://www.cnblogs.com/absi2011/p/9427984.html
Copyright © 2011-2022 走看看