• 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);
    	}
    }



  • 相关阅读:
    Web开发规范
    选择器优先级计算
    CSS 技巧
    CSS3滤镜
    CSS3动画
    css3 <3D 转换>
    CSS3 2D 转换
    CSS3文本(text)模型
    CSS3颜色和渐变
    王道8.6
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3402659.html
Copyright © 2020-2023  润新知