首页 > 代码库 > NOI 1.5 44:第n小的质数
NOI 1.5 44:第n小的质数
---恢复内容开始---
- 描述
-
输入一个正整数n,求第n小的质数。
- 输入
- 一个不超过10000的正整数n。
- 输出
- 第n小的质数。
- 样例输入
-
10
- 样例输出
-
29
- 方法1:合数一定可以表示成一个比它小的质数的几倍,所以若一个数不能整除比它小的所有的质数,则这个数是质数。所以,若要找第n个质数,则可以第n-1个质数为起点开始,通过上述方法判断。
1 #include<iostream> 2 using namespace std; 3 int n,s; 4 int p[10001]; 5 int pan(int t) 6 { 7 while(1) 8 { 9 bool ok=0; 10 for(int i=1;i<=s;i++)//若它是质数,则不不能整除比它小的所有的质数 11 if(t%p[i]==0) 12 { 13 ok=1;break; 14 } 15 if(ok) 16 { 17 t++;continue; 18 } 19 return t; 20 } 21 } 22 int main() 23 { 24 cin>>n; 25 p[1]=2;s++;//s表示当前质数数目 26 for(int i=2;i<=n;i++) 27 { 28 int t=p[s]+1;//下一个质数的至少比上一个质数大1 29 int h=pan(t);//确定下一个质数 30 p[++s]=h; 31 } 32 cout<<p[n]; 33 }
- 方法2:是对方法1的改进,方法1中是判断不能整除所有比它小的质数,结合根号n复杂度判断质数的原理,例:15=3*5,枚举到3时判断了一次,5时又判断了一次,造成重复判断。所以判断能否整除比它小的所有的质数,仅需判断到根号n即可
-
#include<cstdio> #include<cmath> using namespace std; int n,s; int p[100001]; int devide(double k) { int x=(int)k; for(int i=1;i<s;i++) { if(p[i]>=x) return i+1;//因为开立方后的数k强制转化成了整数x,实际上x比k小了,所以要+1 } } int main() { scanf("%d",&n); p[1]=2;p[2]=3; s=2; while(s<n) { int tmp=p[s];//上一个质数 s++;//当前要找的是第s个质数 while(1) { tmp++;//至少比上一个质数大1 bool ok=false; int test=devide(sqrt(tmp));//找到要判断的数开平方后处于哪两个质数之间 for(int i=1;i<=test;i++) if(tmp%p[i]==0) { ok=true; break; } if(ok) continue; p[s]=tmp; break; } } printf("%d",p[n]); }
---恢复内容结束---
NOI 1.5 44:第n小的质数
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。