zoukankan      html  css  js  c++  java
  • poj2689 Prime Distance 有难度 埃拉托斯尼斯筛法的运用

    我承认这道很难(对我来说),搞脑子啊,搞了好久,数论刚开始没多久,还不是很强大,思路有点死,主要是我 天赋太差,太菜了,希望多做做有所改善

    开始解析:

    首先要将在 [ l,u]内的所有素数找出来,还好题目说了u-l 小于 1000 000,不然内存都得暴死了,最常用的方法就是筛法了,当然还有 传说中的 6*n+1 可惜我不会,

    开始假设所有范围内的数都是素数,然后讲所有素数的倍数(肯定不是素数)筛掉,经过无数轮的筛选,余下的就是素数,同时要考虑到所有大于2的偶数都不是素数,可以节省空间,

    使用筛法筛掉[l,u]内的所有非素数,需要知道[l,u]的所有非素数的素因子(因为一个非素数是被它最小的素因子删掉的),2 147 486 647内的数或者是素数,或者能呗根号(2 147 486 647)内的素数正数,也就是说,[l,u]区间的所有非素数的素因子都在 根号(2 147 486 647)内;

    预先将 根号(2 147 483 647)内的所有素数都找出来,然后用这些素数去筛掉指定区间内的所有非素数,

    要考虑到 素数定理来确定做题的范围, n/lnn就是最多的素数个数


    #include<iostream>
    #include<cstdio>
    #include<list>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<stack>
    #include<map>
    #include<vector>
    #include<cmath>
    #include<memory.h>
    #include<set>
    
    #define ll long long
    #define LL __int64
    #define eps 1e-8
    #define e 2.718281828
    //
    //const ll INF=9999999999999;
    
    #define M 400000100
    
    #define inf 0xfffffff
    
    using namespace std;
    
    //vector<pair<int,int> > G;
    //typedef pair<int,int> P;
    //vector<pair<int,int>> ::iterator iter;
    //
    //map<ll,int>mp;
    //map<ll,int>::iterator p;
    //
    //vector<int>G[30012];
    
    bool isprime[50012*20];
    ll prime1[50012],prime2[1000012];
    ll l,u;
    ll numofprime1,numofprime2;//宁可写复杂点也要表达明确意思不误导自己
    
    void dopprime()//筛法,就是模版,直接套上去,注意自己选定的范围,n/lnn
    {
    	memset(isprime,true,sizeof(isprime));
    	isprime[1]=0;
    	numofprime1=0;
    	for(ll i=2;i<=50012;i++)
    	{
    		if(isprime[i])
    		{
    			prime1[++numofprime1]=i;
    			for(ll j=i*i;j<50001;j+=i)
    				isprime[j]=false;
    		}
    	}
    }
    
    void dopprime2()//来筛区间内的非素数
    {
    	ll tmp;
    	memset(isprime,true,sizeof(isprime));
    	for(ll i=1;i<=numofprime1;i++)
    	{
    		tmp=l/prime1[i];
    		while(tmp*prime1[i] < l || tmp <= 1)
    			tmp++;
    		for(ll j=tmp*prime1[i];j<=u;j+=prime1[i])
    		{
    			if(j >= l)
    				isprime[j-l]=false;
    		}
    	}
    	if(l==1)
    		isprime[0]=false;
    }
    
    int main(void)
    {
    	dopprime();//筛法
    	while(~scanf("%lld %lld",&l,&u))
    	{
    		dopprime2();
    		numofprime2=0;
    		ll minn=inf,maxn=-inf;
    		ll minl,minr,maxl,maxr;
    		for(ll i=0;i<=u-l;i++)
    			if(isprime[i])
    				prime2[++numofprime2]=i+l;
    		if(numofprime2 <= 1)
    		{
    			printf("There are no adjacent primes.
    ");
    			continue;
    		}
    		for(ll i=1;i<numofprime2;i++)//找相邻的方法,很简单,但是我居然写错了刚开始
    		{
    			if(prime2[i+1]-prime2[i] < minn)
    			{
    				minn=prime2[i+1]-prime2[i];
    				minl=prime2[i];
    				minr=prime2[i+1];
    			}
    			if(prime2[i+1]-prime2[i] > maxn)
    			{
    				maxn=prime2[i+1]-prime2[i];
    				maxl=prime2[i];
    				maxr=prime2[i+1];
    			}
    		}
    		printf("%lld,%lld are closest, %lld,%lld are most distant.
    ",minl,minr,maxl,maxr);
    	}
    }



  • 相关阅读:
    mojo 接口示例
    MojoliciousLite: 实时的web框架 概述
    接口返回json
    centos 6.7 perl 版本 This is perl 5, version 22 安装DBI DBD
    centos 6.7 perl 5.22 安装DBD 需要使用老的perl版本
    商业智能改变汽车行业
    商业智能改变汽车行业
    读MBA经历回顾(上)目的决定手段——北漂18年(48)
    perl 升级到5.20版本
    Group Commit of Binary Log
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3402659.html
Copyright © 2011-2022 走看看