-
1163题目描述:
-
输入一个整数n(2<=n<=10000),要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数,如果没有则输出-1。
-
输入:
-
输入有多组数据。
每组一行,输入n。
-
输出:
-
输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数(素数之间用空格隔开,最后一个素数后面没有空格),如果没有则输出-1。
-
样例输入:
-
100
-
样例输出:
-
11 31 41 61 71
-
来源:
---------------------------------------------------我是分割线--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
题目1440:Goldbach's Conjecture
分析:第一道题为第二道题提供基础,枚举法固然可以,但工作量大,耗时长,因此选用 素数筛法基本思想:一个素数的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;
}