题目:记录长度为N(1 <= N <= 100000),全部由数字构成,需要多次查询在该记录的第i位后出现的第一个两位素数。
输入
第一行,一个全部由数字构成的字符串,长度小于100000。
第二行,一个整数M(1 <= M <= 100000),表示OYY查询的次数。
第3 … M+2行,每行一个数字Pi(Pi保证不会超过给出字符串的长度且大于零),请求出Pi后一个出现的两位素数。
输出
每个询问一行,输出题目要求的素数,如果不存在输出“-1”。
输入样例
123185154231234984181212132123
6
3
5
8
13
21
30
输出样例
31
23
23
23
13
-1
个人代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char s[100005];
int IsSushu(int sum){//判断是否为素数
int i;
for(i=2;i<sum/2;i++){
if(sum%i==0)
return 0;
}
return 1;
}
int two(int m)//判断是否为两位数
{
if(m>=10) return 1;
else return 0;
}
int main()
{
int i=0,n,recode,j,sum,flag,code,k;
int sss[100005];
memset(sss,-1,sizeof(sss));
while((s[i]=getchar())!='\n'){
i++;
}
s[i]='\0';
for(j=0;j<i;j++){
sum=(s[j]-'0')*10+(s[j+1]-'0');
if(IsSushu(sum)==1&&two(sum)==1){
sss[j]=sum;
for(k=j-1;k>=code;k--)//填充前面没有素数的记录
if(sss[k]==-1)
sss[k]=sss[j];
code=j;//记录上一次填充到的位置,有利于减少次数,也通过判断不等于-1时直接跳出填充的循环
}
}
scanf("%d",&n);
while(n--){
scanf("%d",&recode);
printf("%d\n",sss[recode-1]);
}
return 0;
}
思路:主要思路在于对一个字符串,每次都会寻找相同的东西,字符串太长时,如果每次都去遍历查找,会导致算法复杂度为O(n²);于是可以直接遍历这个字符串,一次性把每个位置对应的素数记录保存下来,节省每次都去遍历花费的时间。