数学中,素数(质数)是只能被1或其本身整除的数。于是,同学们在写代码时,常用如下思路,比如,如何判定43是素数呢?那就用43除以2、3、4、5……42,看看从2-42里,是否存在能整除43的数字,如果存在,43就不是素数,否则,43是素数。于是,可以写出以下代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
for(int i=2;i<n;i++){
if(n%i==0){
cout<<"合数";
return 0;//是合数直接结束
}
}
cout<<"质数";
return 0;
}
思考一下,我们需要暴力2到n-1,太慢了,如何优化一下?
手工计算一下
思考,除到多少就可以了?
a/b=c…k,若a不能被b整除,则a不能被c整除。
我们发现除到n的算术平方根就可以了,也就是sqrt(n),所以对
for(int i=2;i<n;i++)
一句进行优化
for(int i=2;i<sqrt(n);i++)
于是,有了:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
for(int i=2;i<sqrt(n);i++){
if(n%i==0){
cout<<"合数";
return 0;
}
}
cout<<"质数";
return 0;
}
但是,在for内,每次循环都进行开平方操作,显然繁琐了,于是把sqrt(n)提出,在for上边完成k=sqrt(n)的操作。
于是,有了:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
int k=sqrt(n);
for(int i=2;i<k;i++){
if(n%i==0){
cout<<"合数";
return 0;
}
}
cout<<"质数";
return 0;
}
上边这种写法多用行信奥中。
还有一种写法,常在ACM中:
for(int i=2;i<=n/i;i++)
case1:求100以内的所有质数
#include<bits/stdc++.h>
using namespace std;
int main()
{
for(int i=2;i<=100;i++){
int k=sqrt(i);
int flag=0;
for(int j=2;j<=k;j++){
if(i%j==0){
flag=1;
break;
}
}
if(flag==0){
cout<<i<<" ";
}
else flag=0;
}
return 0;
}
case2:求n~m之间的所有质数
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
if(n<2) n=2;
for(int i=n;i<=m;i++){
int k=sqrt(i);
int flag=0;
for(int j=2;j<=k;j++){
if(i%j==0){
flag=1;
break;
}
}
if(flag==0){
cout<<i<<" ";
}
else flag=0;
}
return 0;
}