首页 > 试题广场 >

数素数 (20)

[编程题]数素数 (20)
  • 热度指数:107859 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
令Pi表示第i(i从1开始计数)个素数。现任给两个正整数M <= N <= 10000,请输出PM到PN的所有素数。

输入描述:
输入在一行中给出M和N,其间以空格分隔。


输出描述:
输出从PM到PN的所有素数,每10个数字占1行,其间以空格分隔,但行末不得有多余空格。
示例1

输入

5 27

输出

11 13 17 19 23 29 31 37 41 43<br/>47 53 59 61 67 71 73 79 83 89<br/>97 101 103
import java.util.Scanner;

public class Main {
			

	public static void main(String[] args) {
		// TODO Auto-generated method stub
	
		Scanner in =new Scanner(System.in);
		int n,m;
		m=in.nextInt();
		n=in.nextInt();
		int count = 0;
		int count2 = 0;
		
		for (int i =2;count<=n;i++){
			boolean a =true;
			for (int j =2;j<=(int)Math.sqrt(i);j++)
			{
				
				if (i%j==0)
				{
					a = false;
					break;
				}
			}
			if (a)
			{
				count++;
				if(count>=m&&count<n){
					count2++;
					if(count2!=10){
						System.out.print(i+" ");
					}
					else{
						System.out.println(i);
						count2=0;
					}	
				}
				else if(count==n){
					System.out.print(i);
				}
			}
			
		}
	
	}
	
}
发表于 2017-03-14 20:26:45 回复(0)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
int isprime(int n)
{
    if(n==1) return 0;
    if(n==2) return 1;
    if(n%2==0) return 0;
    int i;
    for(i=3;i<=sqrt(n)+1;i+=2)//遍历到n的平凡根加1
    {
        if(n%i==0)
            return 0;
    }
    return 1;
}
int main()
{
    int N,M,index=1,j=1,count=0;
    scanf("%d%d",&M,&N);
    if(N>10000||M>10000||M>N)
        return -1;
    int array[10001]={0};
     
    while(index<=N)
    {
        if(isprime(j)==1)
        {
            array[index]=j;
            index++;
        }
        j++;
    }
     
    for(j=M;j<=N;j++)
    {
        printf("%d",array[j]);
		count++;
		if(count==10){
			printf("\n");
			count=0;
		}else if(j!=N){
		printf(" ");
		}
    }
    return 0;
}
注意事项:
  • 数组注意下表与M,N的对应;
  • 为图方便直接声明了大小为MAXSIZE的数组,array[M]存的PM,故而数组必须超过10000,否则输入为10000,10000时就会出现数组array[10000]数组访问越界的错误;
  • 输出格式要注意:要求每十个数字要换行,且行末不可有空格。
发表于 2015-08-20 14:42:21 回复(2)
import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int m= in.nextInt();
        int n= in.nextInt();
        int j=1,count=1;
        for (int i=2;i<Integer.MAX_VALUE;i++){
            if (isPr(i)) {
                j++;
                if (j > n+1) {
                    break;
                } else if (j == n + 1 && (j > m) && (count % 10 != 0)) {
                    count++;
                    System.out.print(i);
                } else if ((j > m) && (count % 10 != 0)) {
                    count++;
                    System.out.print(i + " ");
                } else if ((j > m) && (count % 10 == 0)) {
                    count++;
                    System.out.println(i);
                }
            }
        }
    }
 
    public static boolean isPr(int x){
        if (x < 2) {
            return false;
        }
        if (x == 2) {
            return true;
        }
        for (int i = 2;i<=Math.sqrt(x);i++){
            if (x % i == 0) {
                return false;
            }
        }
        return true;
    }
}



发表于 2020-07-26 20:25:54 回复(0)
#include<stdio.h>
int A[100000];
int main(){
    int k=0,i,j,flag=1;
    int m,n;
    scanf("%d %d",&m,&n);
    for(i=2;i<100000;++i){
        flag=1;//每次都重置flag
        for(j=2;j<=(int)(sqrt((double)i));++j){ //注意小于等于根号i
            if(i%j==0){
                flag=0;
                break;
            }
        }
        if(flag==1){
             A[k]=i;
             k++;
        }
    }
    for(i=m-1;i<n;++i){
        if((i-m+2)%10!=0){
            printf("%d ",A[i]);
        }
        if((i-m+2)%10==0){//每输出10个换行
            printf("%d",A[i]);
            printf("\n");
        }
    }
}

为啥格式错误啊,感觉行末没空格和10个换行都有了啊
发表于 2020-03-07 21:38:16 回复(3)
寻找素数问题首先是发现素数存在的规律,我们先来看看素数
2,3,5,7,11,13......
你在序列中会发现
除了2,3以外
素数的存在一定是6x+1或者6x-1,但是6x+1或者6x-1不一定是素数(x为任意正整数)
我们接下来证明
当步长为6的情况中可能存在的数据为
6x-1,6x,6x+1,6x+2,6x+3,6x+4,6x+5,6x+6(=6(x+1))......
这些数据中我们拿6作为步长,可以发现,其中6x能被6整除,6x+2能被2整除,6x+3能被3整除,6x+4也能被2整除,就此只有6x-1和6x+1可能是素数,只需要判断他们是否为素数即可,而6x-1和6x+1又是5和7不断加6变来的我们只需要不断增加(每次为6)他们的值就可以得到可能的素数,在判断即可,想要得到多少个素数也可应用这种办法。
详细参见代码
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
bool isPrime(int num)
{
    int temp=sqrt(num);
    for(int i=5;i<=temp+1;i+=6)
        if(num%i==0||num%(i+2)==0)
            return 0;
    return 1;
}
int main()
{
    int a[4]={2,3,5,7};
    int N,M;
    cin>>M>>N;
    int firstnum=0,firstnum2=0;
    if(M<5)
    {
        for(int i=0;i<5-M;i++)
        {
            firstnum++;
        }
        for(int i=0;i<5-M;i++)
        {
            firstnum2++;
            if(firstnum2>=N)
            {
                cout<<a[4-firstnum+i]<<endl;
                break;
            }
            else
                cout<<a[4-firstnum+i]<<" ";
        }
        
        M=5;
    }
    if(N<5)
        return 0;
    int ok=0;
    int before6=5,after6=7;
    while(ok!=M-5)
    {
        before6+=6;
        if(isPrime(before6))
        {
            ok+=1;
            if(ok==M-5)
                break;
        }
        after6+=6;
        if(isPrime(after6))
        {
            ok+=1;
        }
    }
    int sumout=N-M+1;
    while (sumout!=0)
    {
        before6+=6;
        if(isPrime(before6))
        {
            if(firstnum!=9&&sumout!=1)
            {
                cout<<before6<<" ";
                firstnum+=1;
            }
            else
            {
                cout<<before6<<endl;
                firstnum=0;
            }
            sumout-=1;
            if(sumout==0)
                break;
        }
        after6+=6;
        if(isPrime(after6))
        {
            if(firstnum!=9&&sumout!=1)
            {
                cout<<after6<<" ";
                firstnum+=1;
            }
            else
            {
                cout<<after6<<endl;
                firstnum=0;
            }
            sumout-=1;
        }
    }

    
}


发表于 2020-01-19 09:56:01 回复(1)
  • 埃氏筛法生成素数表。

  • 测试发现10万以内的素数不足1万个,所以应该查找的范围到了100万。

  • 格式输出。

/*
 * app=PAT-Basic lang=c++
 * https://pintia.cn/problem-sets/994805260223102976/problems/994805309963354112
 */
#include <cstdio>
using namespace std;

const int maxn = 1000100; //测试发现10万以内的素数不足1万个,所以应该查找的范围到了100万
bool isPrime[maxn] = {};
int prime[10010] = {};
int len = 0;
void getPrime(){
    for (int i = 2; i < maxn && len < 10010; i++){
        if (!isPrime[i]){
            prime[len++] = i;
            for (int j = i + i; j < maxn; j += i){
                isPrime[j] = true;
            }
        }
    }
}
int main()
{
    getPrime();
    int N, M;
    scanf("%d%d", &M, &N);
    int cnt = 0;
    for (int i = M - 1; i < N;i++){
        printf("%d",prime[i]);
        cnt++;
        if (cnt % 10 == 0){
            printf("\n");
        }
        else if(i!=N-1){
            printf(" ");
        }
    }
    return 0;
}
发表于 2019-12-03 15:48:00 回复(0)
#include<iostream>
#include<math.h>
using namespace std;
bool sushu(int num){
    for(int i=2;i<=sqrt(num);i++){
        if(num%i==0){
            return false;
        }
    }
    return true;
}
int main(){
    int M,N;
    int count=0;
    int Prcount=0;
    cin>>M>>N;
    for(int i=2;;i++){
        if(sushu(i)==1){
            count++;
            if(count>=M){
                if(Prcount==10){
                    cout<<endl;
                    Prcount=0;
                } else if(count>M){
                    cout<<" ";
                }
                cout<<i;
                Prcount++;
            }
            if(count==N){
                break;
            }   
        }
    }
    
    return 0;
}
发表于 2019-07-22 13:23:41 回复(0)
把整个问题拆开成几个小问题:
1.判断素数
2.保存素数
3.如何循环并判断是否结束
4.输出格式
还是初学者的思路,错误之处还望指正
代码如下:
#include <iostream>
#include<cmath>
using namespace std;

int main()
{
    int M,N,count=0;
    long n=2;
    long sushu[10001];
    int x=1;//每行个数
    cin>>M>>N;
    do{
        long i;
        long m=sqrt(n);
        for(i=2;i<=m;i++)
        {
            if(n%i==0)goto loop;
        }
        if(i>m)
        {
            sushu[count]=n;
            count++;
            loop:
            n++;
        }
    }while(count<N);
    if(M==N)
    {
        cout<<sushu[M-1];
    }
    if(M<N)
    {
        for(int j=M;j<=N;j++)
        {
            if(x%10==0)
            {
                cout<<" "<<sushu[j-1]<<endl;
                x++;
            }
            else if(x%10==1)
            {
                cout<<sushu[j-1];
                x++;
            }
            else
            {
                cout<<" "<<sushu[j-1];
                x++;
            }
        }
    }
}

发表于 2019-07-07 11:30:15 回复(0)
做了有点久,关键是运行超时,我就把循环改掉了一部分,以下是我最开始的编程及修改后的
(1)运行超时,循环增大了程序的复杂度
import java.util.Scanner;
public class test03 {

    /**
     * @param arg***r />      */
    public static void main(String[] arg***r />         // TODO Auto-generated method stub
        Scanner sc=new Scanner(System.in);
        short M=sc.nextShort();
        short N=sc.nextShort();
        int su[]=new int[N];
        su[0]=2;    
        for(int j=3,i=1;i<N;j++)
        {
            int f=1;
            for(int k=2;k<j&&f==1;k++)
            {
                int b=j%k;
                if(b==0)
                    f=-1;
            }
            if(f==1)
            {
                su[i]=j;
                i++;
            }
        }
        for(int j=M-1;j<N-1;j++)
        {
            System.out.print(su[j]+" ");
            if((j-M+2)%10==0)
            {System.out.println();}
        }
        System.out.print(su[N-1]);
    }
}

(2)修改后
import java.util.Scanner;
public clas***ain {

    /**
     * @param arg***r />      */
    public static void main(String[] arg***r />         // TODO Auto-generated method stub
        Scanner sc=new Scanner(System.in);
        int M=sc.nextInt();
        int N=sc.nextInt();
        
        int x1=0;
        int x2=0;
        for(int k=2;x1<=N;k++)
        {
            int f=1;
            for(int i=2;i<=Math.sqrt(k);i++)
            {
                if(k%i==0)
                    f=-1;
            }
            if(f==1)
            {
                x1++;
                if(x1>=M&&x1<=N)
                {
                    if(x2==9)
                    {
                        System.out.println(k);
                        x2=0;
                    }
                    else if(x1!=N)
                    {
                        System.out.print(k+" ");
                        x2++;
                    }
                    else
                    {
                        System.out.println(k);
                    }
                }
            }
        }
        
    }
}

发表于 2019-05-21 16:44:26 回复(0)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;

bool isSu(int a){
    if(a <= 1) return false;
    for(int i = 2; i <= sqrt(a); i++){
        if(a % i == 0) return false;
    }
    return true;
}

int su[100010];

int main(){
    int down, up;
    int m = 0, i = 0;
    scanf("%d %d", &down, &up);
    while(m  < up){
        if(isSu(i)) m++;
        if(isSu(i) && m >= down ){
            printf("%d", i);
            if(m != up && !((m - down + 1) % 10 == 0)) printf(" ");
            if((m - down + 1) % 10 == 0) printf("\n");
        }
        i++; 
    }
    return 0;
} 

编辑于 2019-04-29 09:36:29 回复(0)
Python版:
找素数方法(比较重要,不然会超时):首先可以直接利用已经找到的前n个素数来判断;同时找到开平方数附近的数,两个相比较,作为最后测试的数,这样可以节约时间.
#判断是否为素数,结合开平方法和已知的n个素数
def sss(a,b,n):
    for i in range(n):
        if b[i]<=(a/b[i]):
            if a%b[i]==0:
                return [0,n]
        else:
            break;
    return [1,(n+1)]

a = [int(n) for n in input().split()];
b=[0 for n in range(10000)];
b[0]=2;b[1]=3;
p=5;q=2;
d=0;
#只需要找指定的数量
while(q < a[1]):
    k=sss(p,b,q);
    if k[0]==1:
        b[q]=p;
        q+=1;
    p+=1;
    
'''输出结果,注意最后一个数字后面不能有空格,每10个就换行'''
for i in range(a[0]-1,a[1]):
    d+=1;
    if d%10==0:
        print(b[i])
    elif i==(a[1]-1):
        print(b[i])
    else:
        print(b[i],end=' ')          

发表于 2019-03-01 14:43:09 回复(0)

基本思路

素数是指只能被1和自己整除的正整数,所以需要找出因子是本身和1的数,因而能被小于该数的素数整除的数一定不是素数,而小于该数的非素数一定可以被小于该数的素数整除,因而只要该数不能被小于它的所有素数整除,那么该数一定为素数,而素数序列相对于自然数序列要松散的多,故而只需要将该数对小于它的素数取余就可判断该数是否为素数。

示例代码:

#include <iostream>
using namespace std;
struct PrimeNode
{
    PrimeNode *next;
    unsigned long value;
};
int main(){
    int M, N, pIndex = 0;
    unsigned long num = 2;
    string str = "";
    PrimeNode *head = new PrimeNode {
        NULL,
        2
    };
    PrimeNode *p = head;
    cin >> M >> N;
    while(1){
        unsigned long i = 2;
        p = head;
        while(0 != num%(p->value)){
            if(NULL == p->next) break;
            p = p->next;
        }
        if(NULL == p->next) {
            pIndex++;
            p->next = new PrimeNode{NULL, num}; // 添加到素数列表
            if((pIndex >= M) && (pIndex <= N)){
                if((pIndex != M) && (0 == (pIndex - M)%10)){
                    str = "";
                    cout << endl;
                }
                cout << str << num;
                str = " ";
            } else if(pIndex > N){
                break;
            }
        }
        num++;
    }
    cout << endl;
    return 0;
}

时间 得分 结果 题目 语言 用时(ms) 内存(KB)
2018-09-18 5 答案正确 数素数 (20) C++ 441 732

编辑于 2018-09-18 16:17:49 回复(0)
求大神解答:为什么提交总提示格式错误,行末没有空格啊~~~
def allPrime(maxNum):
    aList = [x for x in range(0,maxNum)]
    prime = []
    for i in range(2,len(aList)):
        if aList[i] != 0:
            prime.append(aList[i])
            clear(aList[i],aList,maxNum)
    return prime
      
def clear(aPrime,aList,maxNum):
    for i in range(2,int((maxNum/aPrime)+1)):
        if not aPrime*i>maxNum-1:
            aList[i*aPrime]=0      
        
    

input_max = 10000  
sushu = allPrime(input_max)
list_1 =[]
a,b = map(int, input().split() )  
for i in range(a-1, b):
    list_1.append(sushu[i])

for i in range (len(list_1)):
    if i == (len(list_1) - 1) :
        print(list_1[i], end = '')
    elif (i+1) % 10 == 0 and i != 0:
        print(list_1[i], end = '')
        print('\n')   
    else:
        print(list_1[i], end = ' ')

发表于 2018-08-20 23:02:51 回复(1)
大家好,我想知道为什么我的这个编译通过但是答案错误,实在不知道是哪里错了。 在本地编译器上也试了很多呢,希望有发现我的错误的,感谢指正。
测试用例:
5 21
对应输出应该为 :
        11 13 17 19 23 29 31 37 41 43
        47 53 59 61 67 71 73
你的输出为 :
         5 7 11 13 17 19
我的代码:头文件省略,用的C++写的

//判断num是否为一个素数
bool fun(int num)
{
    for (int j = 2; j<num; j++)
    {
        if (num%j == 0)
        {
            return false;
        }
    }
    return true;
}

void Isprime(int m, int n)
{
    int num = 0;//题目要求每输出10个就换行,用此来计数
    for (int i = m; i <= n; i++)
    {//将m-n的数字一个一个通过fun函数来判断,返回结果
        bool res = fun(i);
        if (res == true)
        {
            cout << i << " ";
            num++;
            if (num % 10 == 0)
                cout << endl;//每10个就换行
        }
    }
}

int main()
{
    int m, n;
    cin >> m >> n;
    Isprime(m, n);
    return 0;
}
发表于 2018-08-13 02:14:33 回复(4)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int VN(int n)
{
    int i;
    for(i=2;i<=sqrt(n);i++)
    {
        if(n%i==0)
            return 0;
    }
    return 1;
}

int main()
{
    int m,n,i,k,s=0,t=1,j=0,x,y=0;
    int a[100000];
    scanf("%d%d",&m,&n);
    for(i=2;;i++)
    {
        if(VN(i))
        {
            t++;
            a[j]=i;
            j++;
        }
        if(t==n+1)break;
    }
    k=(n-m)/10;
    x=(n-m)%10;
    for(i=m-1;i<n;i++)
    {
        y++;
        x=y%10;
      if(x==1)
        printf("%d",a[i]);
      else
        printf(" %d",a[i]);
        if(x==0)
            printf("\n");
    }
 return 0;
}
 
发表于 2018-05-18 15:15:11 回复(0)

include

include

int main()
{
int n,m,i,j,t=0,c=0;
scanf("%d%d",&n,&m);
for(i=2;c<m;i++) { t=sqrt(i); int flag=0; for(j=2;j<=t;j++) if(i%j==0) break; if(j==t+1) { c++; flag=1; } if(c>=n&&flag==1)
{
printf("%d",i);
if((c-n)%10==9)
printf("\n");
else if(c!=m)
printf(" ");
}
}
return 0;
}

发表于 2018-04-16 16:27:35 回复(0)
#include <iostream>
using namespace std;
int num=0;
bool p[1000010]={0};
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=2;num<=m;i++){
        if(p[i]==0){
            num++;
            for(int j=i;j<1000010;j+=i)  //筛除i的倍数
                p[j]=1;
            if(num>=n && num<=m){
                cout<<i;
                if(num!=n && (num-n+1)%10==0) cout<<'\n'; //换行
                else if(num!=m) cout<<" ";
            }
        }
    }    
    return 0;
}

发表于 2018-02-20 16:19:45 回复(0)
#include <iostream>
#include <math.h>
using namespace std;

int get_one()
{
static int res = 2, jia = 0;
int i, ok = 0;
if (jia == 1)
res += 2;
if (res == 3)
{
res += 2;
jia = 1;
return 3;
}
if (res == 2)
{
res++;
return 2;
}
else
{
while (ok == 0)
{
ok = 1;
for (i = 2; i <= sqrt(res); i++)
{
if (res%i == 0)
{
res += 2;
ok = 0;
break;
}
}
}
return res;
}
}

int main()
{
int m, n, i, j, count = 0;
cin >> m;;
cin.get();
cin >> n;
int *a = new int[n+1];

a[0] = 2;
for (i = 1; i <= n; i++)
{
a[i] = get_one();
}
for (i = m-1; i < n; i++)
{
cout << a[i];
count++;
if (count == 10)
{
count = 0;
cout << endl;
}
else if (i != n-1)
cout << " ";
}
return 0;
}

编辑于 2018-01-30 15:08:12 回复(0)
#include "bits/stdc++.h"
using namespace std;
#define MAX 10005
int pri[MAX]= {0},pri_n=1;
bool isPrime(int num)
{
    if(num ==2||num==3)
        return 1;
    if(num %6!=1&&num %6!=5)
        return 0;
    int tmp =sqrt(num);
    for(int i=5; i<=tmp; i+=6)
        if(num%i==0||num %(i+2)==0)
            return 0;
    return 1 ;
}
void se(int t)
{
    int m=2,n=105000,i=0;
    for(i=m; i<n+1; i++)
    {
        if(isPrime(i))
        {
            pri[pri_n]=i;
            pri_n++;
        }
        if(pri_n>t)
            break;
    }
}
int  main()
{
    int m=0,n=0;
    cin>>m>>n;
    se(n);
    int i=0;
    for(i=m; i<n; i++)
    {
        if((i-m+1)%10!=0)
            cout<<pri[i]<<" ";
        else
            cout<<pri[i]<<endl;
    }
    cout<<pri[i];
}
比较麻烦,随便看看吧
编辑于 2017-11-30 15:21:25 回复(0)
/*不用埃拉托斯特尼筛法:
根据素数的定义,判断数n是不是素数,我们只需要从i=2开始,
判断n能不能被n整除,一直到n-1,如果可以则说明不是素数。
另一方面,一个数若是合数,则一定能写成两个因数相乘的形式,并且两个因数中较小的那个一定小于
等于sqrt(n),否则两个因数的乘积大于n,因为i的终止条件可以设为sqrt(n),这种方法的时间复杂度
为O(n的1.5次方)。空间复杂度为O(1)。*/

import java.util.Scanner;

import org.omg.CosNaming._NamingContextExtStub;

public class Main {

	public static void main(String[] args) {
		@SuppressWarnings("resource")
		Scanner _scanner = new Scanner(System.in);
		int M = _scanner.nextInt();
		int N = _scanner.nextInt();
		int num = 1 ;
		
		int primeCount = 0;
		
		//全体素数数表
		int[] _arrWholePrime = new int[N] ;
		//输出素数表
		int[] _arrPrime = new int[N - M + 1] ;
		
		while (true) { //遍历整个整数数表
			num ++ ;
			int count = 0;
			for (int i = 1; i <= Math.sqrt(num); i++) { //遍历从1到num的整数
				if (num % i == 0) {
					++ count; //因数计数,因数包括1和num自身,肯定>=2
				}
			}
			
			if (count == 1) {
				++ primeCount; //找到一个素数
				_arrWholePrime[primeCount - 1] = num; //素数计入数组
			} 
			
			if (primeCount == N) {
				break ;
			}
		}
		
	
		for (int j = 0; j < _arrPrime.length; j++) {
			
			_arrPrime[j] = _arrWholePrime[j + M - 1];
			
			if (((j + 1) % 10 == 0) || j == _arrPrime.length - 1) {
				System.out.println(_arrPrime[j]);
			} else {
				System.out.print(_arrPrime[j] + " ");
			}
			}

	}

}

发表于 2017-08-06 13:50:43 回复(0)