当前位置: 首页 > news >正文

xtuoj 素数

题目

思路

关键点:如何得到所有的区间,如何判断是否为素数

首先解决如何得到所有的区间的问题。由前面进制转换的经验,我们可以知道,我们想要得到所有的区间,应该以字符串的形式读入,然后再将字符串转换为数字。如何将数字字符转换为数字,通过ascii码字符之间的关系知,只需 - '0' 即可如何将字符串转为数字,只要把每个数字乘以他对应的权重再相加即可。常用的一个操作是num=num*base+digit,num首先初始化为0,然后从这里的digit依次从高位到低位取,最后得到的就是转换成数字以后的。要确定一个区间,肯定要先确定它的起点和终点,这里我们以 i 为起点,j 为终点,通过以下操作实现取得每个区间。下面的思路非常类似求最长子列和获取子列的思路。

for(int i=0;i<len;i++){ll num=0;for(int j=i;j<len;j++){num=num*10+(s[j]-'0');if(is_prime(num)) ans++;}}

这段代码中用 s[j] - '0' 获取当前位的数字,配合配合内层循环中对 num 的更新逻辑,确实是一个非常巧妙的优化,核心在于利用已有计算结果避免重复运算,具体可以这样清晰描述:

  1. s[j] - '0' 的作用:字符串 s 中存储的是字符形式的数字(比如 '1''2'),通过 s[j] - '0' 可以将字符转为对应的整数(比如 '1' - '0' = 1),这是获取数字值的常规操作。

  2. num 的更新逻辑:复用已有结果,减少计算量

    • 外层循环确定起点 i 后,num 仅初始化一次为 0
    • 内层循环中,j 从 i 逐渐增加到 len-1(即终点从起点开始不断后移):
      • 当 j = i 时,num 首次计算为 s[i] - '0'(即起点位置的数字)。
      • 当 j = i+1 时,num 无需重新从 i 到 i+1 计算,而是通过 num = num * 10 + (s[j] - '0') 得到:相当于将上一步的结果(i 到 i 的数字)左移一位(乘以 10),再拼接上 j=i+1 位置的数字,直接得到 i 到 i+1 的完整数字。
      • 后续 j 继续增加时,重复上述逻辑:每次都基于上一个区间(i 到 j-1)的结果,左移一位后拼接新的数字 s[j],即可得到当前区间(i 到 j)的数字。
  3. 优势:这种方式避免了 “每次计算新区间时都从起点 i 重新遍历到终点 j” 的重复操作,而是通过 “累加拼接” 的方式复用之前的计算结果,将原本 O(n²) 的时间复杂度优化为实际执行中的线性操作(每个区间仅需一次简单运算),大大提升了效率。

例如,对于 s = "123"i=0 时:

  • j=0num = 0 * 10 + 1 = 1(区间 [0,0]);
  • j=1num = 1 * 10 + 2 = 12(区间 [0,1],复用了 j=0 的结果 1);
  • j=2num = 12 * 10 + 3 = 123(区间 [0,2],复用了 j=1 的结果 12)。

整个过程无需重复计算已处理过的位,逻辑简洁且高效。

再解决判断素数问题。这里直接使用试除法就好了,之前我本来打算用埃式筛法加预处理的,后来发现不行,这样的操作使用于那种n<10^6这种且需要进行大量判断素数的情况,也就是说n差不多10^6,然后T也比较大的时候。这里的n是10^9,而且埃式筛法和欧拉筛法都需要额外用一个数组存素数,比较时候打表,判断一片区间的情况。

这里我加了一个小小的优化,但其实没啥区别,就是把偶数的全都排除,记得要把2设为素数。

bool is_prime(int n){if(n<2) return false;if(n==2) return true;if(n%2==0) return false;for(int i=3;i<=n/i;i+=2)if(n%i==0) return false;return true;
}

还可以在把3的倍数也去掉

bool is_prime(long long n) {if (n < 2) return false;if (n == 2) return true;if (n % 2 == 0) return false;if (n == 3) return true;if (n % 3 == 0) return false;long long limit = sqrt(n) + 1;for (long long i = 5; i <= limit; i += 6) {if (n % i == 0 || n % (i + 2) == 0) {return false;}}return true;
}

当然普通的试除法就够了

bool is_prime(int n){if(n<2) return false;if(n==2) return true;for(int i=2;i<=n/i;i++){if(n%i==0) return false;}return true;
}

代码

#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#define ll long longint T,ans;
char s[10];bool is_prime(int n){if(n<2) return false;if(n==2) return true;if(n%2==0) return false;for(int i=3;i<=n/i;i+=2)if(n%i==0) return false;return true;
}void game(){scanf("%s",s);int len=strlen(s);ans=0;for(int i=0;i<len;i++){ll num=0;for(int j=i;j<len;j++){num=num*10+(s[j]-'0');if(is_prime(num)) ans++;}}printf("%d\n",ans);
}int main(){scanf("%d",&T);while(T--){game();}return 0;
}
http://www.dtcms.com/a/598426.html

相关文章:

  • 静态路由综合实验【实验报告】
  • 电影网站这么做关键词电子产品展示网站
  • 新加坡网站建设公司涡阳在北京做网站的名人
  • JavaScript面试手写题(持续更新)
  • 网站首页的head标签内wordpress标题太长
  • SpringMVC整理
  • 网站会员发展计划ip安装wordpress
  • 【计算思维】蓝桥杯STEMA 科技素养考试真题及解析 5
  • 网站创建软件画质优化app下载
  • 什么做网站成都微信网站制作
  • 如何本地搭建网站新浪微博登录网页版
  • 用 Docker Compose 管理留言板多容器应用
  • 国内网站设计案例做俄语网站
  • 厦门市湖里区建设局网站找别人做网站
  • 南阳企业网站建设公司天推广人的网站
  • 邢台网站制作多少钱哪些论坛是wordpress
  • 手机可以访问的网站怎么做百度应用商店官网
  • 2025年11月11日 AI快讯
  • 性能测试系统综述类型指标与流程协同
  • 头歌MySQL——单表查询
  • 哪个公司的app软件定制seo搜索如何优化
  • 网站后台管理破解漯河市住房和城乡建设局网站
  • Android系统定制——导航栏添加自定义按钮
  • 嵌入式Linux学习——环境变量与配置文件的关系(⭐难理解)
  • LIN总线基础讲解之二—LIN总线网络的物理层与帧结构
  • 十三、More Deeper:VGG详解,从网络结构到实战
  • 天台网站建设大丰有做网站的
  • 网站建设公司利润怎么样利用网站制作网页
  • 单端口RAM IP核
  • 26、【Ubuntu】【远程开发】内网穿透:密钥算法介绍(二)