【重点】九度OJ 1163&1440/HDOJ 1397 Goldbach's Conjecture(素数筛法)

1163题目描述:

输入一个整数n(2<=n<=10000),要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数,如果没有则输出-1。

输入:

输入有多组数据。
每组一行,输入n。

输出:

输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数(素数之间用空格隔开,最后一个素数后面没有空格),如果没有则输出-1。

样例输入:
100
样例输出:
11 31 41 61 71
来源:

2008年北京航空航天大学计算机研究生机试真题

---------------------------------------------------我是分割线--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


题目1440:Goldbach's Conjecture

时间限制:1 秒

内存限制:128 兆

特殊判题:

提交:1822

解决:1124

题目描述:

Goldbach's Conjecture: For any even number n greater than or equal to 4, there exists at least one pair of prime numbers p1 and p2 such that n = p1 + p2. 
This conjecture has not been proved nor refused yet. No one is sure whether this conjecture actually holds. However, one can find such a pair of prime numbers, if any, for a given even number. The problem here is to write a program that reports the number of all the pairs of prime numbers satisfying the condition in the conjecture for a given even number.

A sequence of even numbers is given as input. Corresponding to each number, the program should output the number of pairs mentioned above. Notice that we are interested in the number of essentially different pairs and therefore you should not count (p1, p2) and (p2, p1) separately as two different pairs.

输入:

An integer is given in each input line. You may assume that each integer is even, and is greater than or equal to 4 and less than 2^15. The end of the input is indicated by a number 0.

输出:

Each output line should contain an integer number. No other characters should appear in the output.

样例输入:
6
10
12
0
样例输出:
1
2
1
分析:第一道题为第二道题提供基础,枚举法固然可以,但工作量大,耗时长,因此选用 素数筛法

基本思想:一个素数的k倍一定是非素数,从2~10000遍历,如果i为素数则将该i放至素数数组,并将i的k(k=i*i,(i+1)*i,(i+2)*i,.........)倍的标记标为true,表示该数不为素数,遍历到该数时跳过该数。注意两点:为什么k从i*i,开始而不是从2*i 开始?因为当系数m<i时,m*i已经被当i=m时标记过了,因此不需要从k=2*i开始,可进一步减少工作量。还有,引入了bool型变量IsPrint,有两个作用,1、输出要求开头和结尾没有空格,用IsPrint 来控制空格的输出  2、用该变量来标记是否存在符合条件的值

第二道题,大致意思是一个猜想:任何一个偶数都可以用至少一对素数相加而得到,输入一个大于等于4的偶数,输出有几对这样的素数。


第一题代码如下:


#include <stdio.h>

int Prime[10001];
int PrimeSize;
bool mark[10001];
void Init()
{   int i;
    //初始化
	PrimeSize=0; 
	for(i=1;i<10000;i++)
	{
		mark[i]=false;
	} 
	for(i=2;i<10000;i++)
	{   //i要从2开始 
		if(mark[i]==true) continue;//如果被标记为非素数,则跳过
		Prime[++PrimeSize]=i;
		int j;
		//把该素数的所有倍数标记为非素数,从i开始是因为,比i小的,如 k =2,已经在i=2时标记过了,不需要标记,减少工作量  
		for(j=i*i;j<=10000;j+=i)
		{
			mark[j]=true;
		}
	}
	
}


int main(int argc, char** argv) {
	
	Init(); 
	int n;
	while(scanf("%d",&n)!=EOF){
		int i; 
		bool IsPrint=false;
		for(i=2;i<=PrimeSize;i++){
			//满足个位为1 
			if(Prime[i]<n&&Prime[i]%10==1)
			{   //如果是第一次输入,则不用输出空格 
				if(IsPrint==false)
				{
				 IsPrint = true;
				 printf("%d",Prime[i]);	
				}
				else printf(" %d",Prime[i]);
				
			}
		}
		//如果不存在则输出-1 
		if(IsPrint==false)
		printf("%d",-1);
		//最后换行不要忘了 
		printf("\n");
		
		
	}
	
	
	
	
	return 0;
}

第二道题:

注:这道题用不到Prime数组去存素数都是哪些了,只需要mark来判断是否为素数即可,通过小范围内的枚举O(n)遍历,

      判断自身以及另一个数是否也为素数。这里犯了两个错误,一开始用了Prime数组通过二重遍历相加等于x,计数,果断超时

      第二个错误,没有看清题目给出的范围要求,[4,32768),左闭右开,判断条件写的都是i<=32768,一直WA,气的跺脚。

#include <stdio.h>


bool mark[32768]; 
void Init(){
	int i;
	for(i=1;i<=32767;i++){
		mark[i]=false;
	}
	for(i=2;i<=32767;i++)
	{
		if(mark[i]==true) continue;
		int j;
		for(j=i*i;j<=32767;j+=i)
		{
			mark[j]=true;
		}
	}
	
}

int GetPairNum(int x)
{   int i;
    int cnt=0;
    for(i=2;i<=x/2;i++)
    {  
       if(mark[i]==false&&mark[x-i]==false) cnt++;
    }
    return cnt; 
}

int main(int argc, char** argv) {
	int x;
	Init();
	while(scanf("%d",&x)!=EOF&&x!=0){
		int num=GetPairNum(x);
		printf("%d\n",num);

	}
	
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值