Description
对于表达式n^2+n+41,当n在(x,y)范围内取整数值时(包括x,y)(-39<=x<y<=50,判定该表达式的值是否都为素数。
Input
输入数据有多组,每组占一行,由两个整数x,y组成,当x=0,y=0时,表示输入结束,该行不做处理。
Output
对于每个给定范围内的取值,如果表达式的值都为素数,则输出"OK",否则请输出“Sorry”,每组输出占一行。
-------------------------分割线-------------------------------------------
这道题其实很简单(个甚
设f(n)=n^2+n+41
首先我们求出n的数值
然后判定f(n)是否是一个素数,是的话继续枚举n,否则输出“Sorry”,并跳出循环
于是核心问题变成——如何求一个数是否为素数
我们先上一个O(n)的判定程序
bool check(int x) { if(x<=1) { return 0; } if(x==2) { return 1; } for(int i=2;i<=x;i++) { if(x%i==0) { return 0; } } return 1; }
果断TLE啊!
我们仔细观察,发现√m之后的枚举是不必要的
至于为什么,我决定让你们自己思考(逃
其实挺简单的,仔细想想吧!
于是我们可以得到另一个玄学正常代码
bool check(int x) { if(x<=1) { return 0; } if(x==2) { return 1; } for(int i=2;i<=x;i++) { if(x%i==0) { return 0; } } return 1; }
时间复杂度O(√n)
可以很愉快地把我们这边另一个OJ的数据水过去
然后嘞?有没有更快的?
有!
那个方法,就是传说中的——
欧拉筛法!
(抱歉我的中二病又双叒叕犯了)
它可以在线性时间内求出从x到y中所有整数是否是素数!
但是我老是写错
这里给出模板,如何应用到这道题里就看你们的啦!
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 7 int pri[10000010]; 8 bool vis[10000010]; 9 int cnt,t,n=1e7; 10 11 void get_prime() 12 { 13 vis[0]=vis[1]=1; 14 for(int i=2;i<=n;i++) 15 { 16 if(!vis[i]) 17 { 18 pri[++cnt]=i; 19 } 20 for(int j=1;j<=cnt&&i*pri[j]<=n;j++) 21 { 22 vis[i*pri[j]]=1; 23 if(i%pri[j]==0) 24 { 25 break; 26 } 27 } 28 } 29 }