您的位置:首页 > 大数据 > 人工智能

TOJ 1006 Redraiment猜想 (求素数)

2016-12-10 10:37 176 查看
题目的意思:给你一个(1~100000000)的数n,让你求1~n之间有多少个素数.

第一想法:利用下面代码求m~n之间素数,时间复杂度为nlgn,不用看就超时.

for(int i=m;i<=n;i++){
if(i==0 || i==1){
continue;
}
flag=1;
for(int j=2;j*j<=i;j++){
if(i%j == 0){
flag=0;
break;
}
}
}


想法二:筛选加打表
#include<stdio.h>
int arr[1500];
int count = 0;
int MAX = 100000010;
bool flag[100000020];//用来判断是否为素数
void prime(int m,int n){//求m~n之间的素数
int cnt=1;
for(int i=m;i<=n;i++){
if(i ==0 || i==1){
continue;
}
cnt=1;
for(int j=2;j*j<=i;j++){
if(i%j==0){
cnt=0;
break;
}
}
if(cnt==1){
arr[count++]=i;
//System.out.println(i);
}
}
}

int main(){
int num[1001];
prime(0,10000);
for(int i=0;i<count;i++){//筛选,利用小素数筛选
int t=arr[i];
for(int j=arr[i]*arr[i];j<=MAX;j=arr[i]*t){
flag[j] = true;
t++;
}
}
flag[0] = true;
flag[1] = true;
int cnt=0;
for(int i=0;i<=MAX;i++){//打表
if(!flag[i]){
cnt++;
}
if(i%100000==0){
num[i/100000] = cnt;
}
}
int n;
while(~scanf("%d",&n) && n){
int sum=0;
sum = sum + num[n/100000];
for(int i=n/100000*100000;i<=n;i++){
if(!flag[i]){
sum++;
}
}
printf("%d\n",sum);
}
}


恩,没错还是超时!当时就想不通这得怎么过.在细看一下题目,只要求个数,想到了容斥原理.
想法三:容斥原理+筛选

容斥原理不会的去这个看看

http://www.cppblog.com/vici/archive/2011/09/05/155103.html

然后就是 :奇加偶减

#include<stdio.h>
int arr[1500];//用来存储10000以内的素数
int count=0; //记录10000以内素数的个数
void prime(int m,int n){//求素数
int cnt=1;
for(int i=m;i<=n;i++){
if(i ==0 || i==1){
continue;
}
cnt=1;
for(int j=2;j*j<=i;j++){
if(i%j==0){
cnt=0;
break;
}
}
if(cnt==1){
arr[count++]=i;
}
}
}
int main(){
prime(0,10000);
int m;
//2*3*5*7*11*13*17*19*23>100000000
while(~scanf("%d",&m) && m){
int sum = m-1;
int n=m,n1,n2,n3,n4,n5,n6,n7;
for(int i=0;i<count && arr[i]<=n;i++){
n=m;
sum = sum - (n/arr[i]-1);//在这其中包含了素数其自身
n1 = n/arr[i];
for(int j=i+1;j<count && (n1/arr[j]>0);j++){
sum = sum + n1/arr[j];
n2 = n1/arr[j];
for(int k=j+1;k<count && (n2/arr[k]>0);k++){
sum = sum -n2/arr[k];
n3 = n2/arr[k];
for(int a=k+1;a<count && n3/arr[a]>0;a++){
sum = sum + n3/arr[a];
n4 = n3/arr[a];
for(int b=a+1;b<count && n4/arr[b]>0;b++){
n5 = n4/arr[b];
sum = sum - n4/arr[b];
for(int c=b+1;c<count && n5/arr[c]>0;c++){
n6 = n5/arr[c];
sum = sum + n5/arr[c];
for(int d=c+1;d<count && n6/arr[d]>0;d++){
n7 = n6/arr[d];
sum = sum - n6/arr[d];
for(int e=d+1;e<count && n7/arr[e]>0;e++){
sum = sum + n7/arr[e];
}
}
}
}
}
}
}
}
printf("%d\n",sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息