• 素数问题三步曲_HDOJ2098


    偶然间OJ上敲到一题素数问题便查询了相关算法。对于该类问题我个人学习分为三步曲:最笨的方法(TLE毫无疑问)->Eratosthrnes筛选法->欧拉线性筛选法

    针对HDOJ2098这道题进行代码分析,发散性可以解决其他问题。

    笨笨的方法(TLE)

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    int main()
    {
    	int a,b,n;
    	while(1)
    	{
    		scanf("%d",&n);
    //		printf("这是输入的数:%d
    ",n); 
    		if(n==0) break;
    		int i=1,sum=0;
    		for(i=2;i<n/2;i++)
    		{
    			//判断i,n-i两者是否都是素数
    			int j=2,flag=0;
    			for(j=2;j<=i/2;j++)
    			{
    				if(i%j==0)
    				{
    					flag=1;
    					break;
    				}
    			}
    //			printf("第一次判断i是否为素数结束
    "); 
    			for(j=2;j<=(n-i)/2;j++)
    			{
    				if((n-i)%j==0||(n-i)==1)
    				{
    					flag=1;
    					break;
    				}
    			}
    //			printf("第二次判断n-i是否为素数结束
    ");
    			if(flag==0)
    			{
    //				printf("此时i和n-i都是素数:%d %d
    ",i,n-i);
    				sum++;
    			}
    		}
    		printf("%d
    ",sum);
    	}
    	return 0;
    } 
    

    Eratorsthenes筛选法(AC)

    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    #include<string.h>
    
    #define MAX 100000
    bool num[10000]={false,false,true};
    
    int main()
    {
    	int n;
    	int i=0,j=0;
    	for(i=3;i<10000;i++)
    	{
    		//初始化所有的数都为素数 
    		num[i]=true;
    	}
    		
    	//从2开始对所有素数的倍数置为false 
    	for(i=2;i*i<10000;i++)
    	{
    		if(num[i]==true)
    		{
    			for(j=i*i;j<10000;j+=i)
    			{
    				num[j]=false;
    			}
    		}
    	}
    	//检测输出所有比10000小的素数序列 
    //	for(i=1;i<10000;i++)
    //	{
    //		if(num[i]==true)
    //			printf("%d ",i);
    //	}
    	
    	while(1)
    	{
    		int cnt=0;
    		scanf("%d",&n);
    		if(n==0) break;
    	
    		for(i=2;i<n/2;i++)
    		{
    			if(num[i]==true&&num[n-i]==true)
    			{
    				cnt++;
    			}
    		}
    		printf("%d
    ",cnt);
    	}
    	return 0;
    }
    

    Eratorsthenes筛选法(复杂度nlogn)是素数问题中十分有名的解法:即要求N以下的所有为素数的数有多少个?我们需要检查到sqrt(n)是否存在素数即可。

    1. 假设有一个筛子存放1~N的数。2 3 4 5 6 7 8 9 10 11 12 ...N
    2. 先将2的倍数筛选出去(一定不为素数)2 3 5 7 9 11 13 17 19...N
    3. 将3的倍数筛选出去(一定不为素数)2 3 5 7 11 13 17 19...N
    4. 即不断对当前剩下的数列中最前面的数的倍数从数列中筛选出去,最后剩下的数列即为所有比N小的素数序列。

    欧拉线性筛选法

    我们可以发现在Eratorthenes筛选法中,30,这个数,在215中被筛了一次,在56中又被重复筛了,所以对于此处可以进行优化修改。但是我对于其中算法关键看了一会不是很懂,目前就暂时不写吧。

  • 相关阅读:
    使用gitlab, jenkins搭建CI(持续集成)系统(1) -- 准备环境
    后台开发技术(2)--接入层设计
    后台开发技术(1)--概述
    【Go】学习笔记兼吐槽(1)
    【PyCharm】书签的使用
    【pygame】Python 不到 300 行代码实现俄罗斯方块
    【杂谈】详解医保报销
    【Python 库】requests 详解超时和重试
    【Python 库】读取 .doc、.docx 两种 Word 文件简述及“Word 未能引发事件”错误
    【Python】鲜为人知的功能特性(下)
  • 原文地址:https://www.cnblogs.com/heihuifei/p/10445240.html
Copyright © 2020-2023  润新知