素数:又称质数(prime number),有无限个。
质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数的数称为质数。
判断一个数n是否为素数:从2开始到sqrt(n)是否有可以整除n的数,若存在,则不为素数;否则为素数。
时间复杂度:O(sqrt(n))
题目1047:素数判定
时间限制:1 秒内存限制:32 兆特殊判题:否提交:14099解决:6378
题目描述:
给定一个数n,要求判断其是否为素数(0,1,负数都是非素数)。
输入:
测试数据有多组,每组输入一个数n。
输出:
对于每组输入,若是素数则输出yes,否则输入no。
样例输入:
13
样例输出:
yes
#include <iostream>
#include<math.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
int n;
bool isPrime(int n){
bool ans=true;
int bound=sqrt(n);
for(int i=2;i<=bound;i++){
if(n%i == 0){
ans=false;
break;
}
}
return ans;
}
int main(int argc, char *argv[]) {
while(cin>>n){
if(n>1 && isPrime(n) == true){
cout<<"yes"<<endl;
}else{
cout<<"no"<<endl;
}
}
return 0;
}
素数筛选法:
原理:若一个数不是素数,则必存在一个小于它的素数因子。
当获得一个素数时,即将它所有的倍数进行标记为非素数。
当一个数没有被标记,则表明其为素数。
可能存在一个数没有被标记但是是非素数吗?
假设存在一个非素数N,它没有被标记,即N不存在一个比它小的素数因子,也就是N除了1和N以外没有能够整除N的数,那么N就是个素数,与假设矛盾。因此,不可能存在一个数没有被标记却是非素数。
题目1163:素数
时间限制:1 秒内存限制:32 兆特殊判题:否提交:13205解决:4627
题目描述:
输入一个整数n(2<=n<=10000),要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数,如果没有则输出-1。
输入:
输入有多组数据。
每组一行,输入n。
输出:
输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数(素数之间用空格隔开,最后一个素数后面没有空格),如果没有则输出-1。
样例输入:
100
样例输出:
11 31 41 61 71
来源:
2008年北京航空航天大学计算机研究生机试真题
代码:
#include <iostream>
#define N 10001 //筛选出2-10000之间的所有素数
using namespace std;
/*
输入一个整数n(2<=n<=10000),
要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数,
如果没有则输出-1。
*/
int prime[N]; //保持筛选出的素数
int primelength=0; //记录筛选出的素数的个数
int mark[N];
void findPrime(){
//素数筛选
//1.初始化所有数字都没有被标记
for(int i=0;i<N;i++){
mark[i]=false;
}
//2.开始筛选
for(int i=2;i<N;i++){
if(mark[i] == true){
continue; //该数已经标记了
}
mark[i]=true; //否则就标记该数
prime[primelength++]=i;
//cout<<i<<endl;
for(int j=i*i;j<N;j+=i){ //标记i的倍数
mark[j]=true;
}
}
}
int main(int argc, char *argv[]) {
//1.预处理筛选出素数
findPrime();
//2.从筛选出的素数选择出符合条件的素数
int n;
while(cin>>n){
bool exits=false; //标记是否有满足条件的素数
for(int i=0;i<primelength;i++){
if(prime[i] < n ){
if(prime[i]%10 == 1){
if(exits == false){ //第一个素数
cout<<prime[i];
}else{
cout<<" ";
cout<<prime[i];
}
exits=true;
}
}else{ //素数已经大于n,则停止
break;
}
}
if(exits == false){
cout<<"-1";
}
cout<<endl;
}
return 0;
}
其中素数筛选的模板为:
#include <iostream>
#define N 10001 //筛选出2-10000之间的所有素数
using namespace std;
/*
输入一个整数n(2<=n<=10000),
要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数,
如果没有则输出-1。
*/
int prime[N]; //保持筛选出的素数
int primelength=0; //记录筛选出的素数的个数
int mark[N];
void findPrime(){
//素数筛选
//1.初始化所有数字都没有被标记
for(int i=0;i<N;i++){
prime[i]=false;
}
//2.开始筛选
for(int i=2;i<N;i++){
if(mark[i] == true){
continue; //该数已经标记了
}
mark[i]=true; //否则就标记该数
prime[primelength++]=i;
//cout<<i<<endl;
for(int j=i*i;j<N;j+=i){ //标记i的倍数
mark[j]=true;
}
}
}
其中判定i为素数时,标记从i*i开始而不是2*i的原因是
k * i( k < i ) 的数已经在求得k的素因数的时候标记了。