zoukankan      html  css  js  c++  java
  • poj:2689用筛选法选素数求区间[L,U]的所有素数

    //http://poj.org/problem?id=2689
    
    #include <bitset>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    
    typedef unsigned int uint;
    /*
    原理:
    
    1) 2的倍数都是合数(2除外)
    
    2) 给定一个N, N*i(i>1)都是合数
    
    算法:
    
    1) 假设所有数都是素数
    
    2) 2的倍数为合数
    
    3) 设3<=N<=sqrt(U)+1且N为奇数,则N * i(i>1)的倍数为合数
    */
    bool* GetPrimeNumbers(uint L, uint U,bool Cands[])
    {
    	const uint N = U-L +1;
    	memset(Cands,1,N);	
    	for(uint i = L%2==0?0:1;i<N;i+=2)
    	{
    		Cands[i] = false;
    	}
    	uint end = sqrt((double)U)+1;
    	for(uint i = 3;i<end;i+=2)
    	{
    		if(i>=L&&Cands[i-L]==false) //i是合数,不需要继续筛选
    			continue;
    		uint j = L/i*i;
    		if(j<L)
    		{
    			j+=i;
    		}
    		if(j==i)
    			j+=i;
    		for(j = j-L;j<N;j+=i)
    		{
    			Cands[j] = false;
    		}		
    	}
    	if(L==2)
    		Cands[0] = true;
    	return Cands;
    }
    
    bool GetMinMax(bool * Cands,const uint N,int &C1,int &C2, int&D1,int &D2)
    {
    	C1 = C2 = D1 =D2 = -1;
    	int pre = 0;
    	int min = 0;
    	int max = 0;
    	for(uint i =0;i<N;++i)
    	{
    		if(Cands[i]==true)
    		{
    			if(C1 == -1)
    			{
    				C1 = D1 = i;
    			}
    			else if(C2 == -1)
    			{
    				C2 =D2 = i;
    				min = max = C2 -C1;
    			}
    			else
    			{
    				if(i-pre<min)
    				{
    					C1 = pre;
    					C2 = i;
    					min = C2-C1;
    				}
    				else if(i- pre > max)
    				{
    					D1 = pre;
    					D2 = i;
    					max = D2 -D1;
    				}
    
    			}
    			pre =i;			
    		}
    	}
    	return min != 0;
    }
    
    bool GetMinMax(uint L,uint U,int &C1,int &C2, int&D1,int &D2)
    {
    	if(L<2)
    		L=2;
    	static uint const SIZE = 10000002;
    	static bool Cands[SIZE];
    	const uint N = U-L +1;
    	GetPrimeNumbers(L,U,Cands);
    	if(GetMinMax(Cands,N,C1,C2,D1,D2))
    	{
    		C1+=L;
    		C2+=L;
    		D1+=L;
    		D2+=L;
    		return true;
    	}
    	return false;
    }
    
    int main()
    {
    	uint L,U;
    	while(cin>>L>>U)
    	{
    		int C1,C2,D1,D2;
    		if(GetMinMax(L,U,C1,C2,D1,D2))
    		{			
    			printf("%d,%d are closest, %d,%d are most distant.\n",C1,C2,D1,D2);
    		}
    		else
    		{
    			printf("There are no adjacent primes.\n");
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    MySQL数据库安装和基本使用
    Android studio JNI技术实现与本地C++链接
    笔记 java中i++ 和 ++i的区别
    LaTeX中添加usepackage{subfigure}一直报错的解决办法,亲测
    Android Studio 出现“Cannot resolve symbol” 解决办法
    记录一个sql
    linux 文件内容查找、去重、统计
    MVC框架的模板缓存
    Linux 命令学习
    笔记 :PHP中的数据结构库SPL
  • 原文地址:https://www.cnblogs.com/SammyLan/p/2172471.html
Copyright © 2011-2022 走看看