【NOI-题解】1137 - 纯粹素数1258 - 求一个三位数1140 - 亲密数对1149 - 回文数个数

文章目录

  • 一、前言
  • 二、问题
    • 问题:1137 - 纯粹素数
    • 问题:1258 - 求一个三位数
    • 问题:1140 - 亲密数对
    • 问题:1149 - 回文数个数
  • 三、感谢

一、前言

欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》

本章节主要对自定义函数问题进行讲解,包括《1137 - 纯粹素数》《1258 - 求一个三位数》《1140 - 亲密数对》《1149 - 回文数个数》题目。

二、问题

问题:1137 - 纯粹素数

类型:自定义函数


题目描述:

纯粹素数是这样定义的:一个素数,去掉最高位,剩下的数仍为素数,再去掉剩下的数的最高位,余下的数还是素数。这样下去一直到最后剩下的个位数也还是素数。

求出所有小于 3000 的四位的纯粹素数。

输入:

输出:

按从小到大的顺序输出若干个纯粹素数,每行一个。

在这里插入图片描述


1.分析问题

  1. 已知:所有小于3000的四位数。
  2. 未知:求出所有小于 3000 的四位的纯粹素数。
  3. 关系: 纯粹素数:一个素数,去掉最高位,剩下的数仍为素数,再去掉剩下的数的最高位,余下的数还是素数。这样下去一直到最后剩下的个位数也还是素数。

2.定义变量

	//二、定义变量(已知、未知、关系) 
	int t;
	bool isFind;

3.输入数据

无。

4.数据计算

  • isPrime 函数:这个函数用于检测一个整数 p 是否为素数。
    • 首先处理特殊情况:小于等于3的数,其中1不是素数,2和3是素数。
    • 然后排除所有能被2或3整除的数。
    • 最后,从5开始,每次增加6,检查形如 6k ± 1 的数是否能整除 p。这是因为除了2和3外,所有素数都可以表示为 6k ± 1 的形式。
bool isPrime(int p){
	if(p<=3) return p>1;
	
	if(p%2==0 || p%3==0) return false;
	
	for(int i=5;i*i<=p;i+=6){
		if(p%i==0||p%(i+2)==0) return false;
	}
	
	return true;
}


  • reHigh 函数:这个函数用于去掉一个数的最高位。
    • 如果数小于等于9,则返回0(因为已经没有更高位可以去掉了)。
    • 使用模运算和除法来构建新的数,去掉最高位。
int reHigh(int r){	
	if(r<=9) return 0;
	int res=0,mul=1;
	while(r>9){
		res+=r%10*mul;
		r/=10;
		mul*=10;
	}
	return res;
}
  • 遍历从1001到2999之间的所有奇数(因为除了2以外的所有偶数都不是素数)。
    • 对于每个数,检查它及其去掉最高位后的数是否均为素数。
    • 如果是纯粹素数,则输出该数。
//四、根据关系计算
	for(int i=1001;i<3000;i+=2){
		t=i;
		isFind=true;
		while(t){
			if(!isPrime(t)){
				isFind=false;
				break;	
			}
			t=reHigh(t);
		}
		//五、输出未知 
		if(isFind) cout<<i<<endl;
	} 

完整代码如下:

#include<bits/stdc++.h>
using namespace std;

// 检测一个整数是否为素数
bool isPrime(int p){
    // 处理特殊情况:小于等于3的数
    if(p <= 3) return p > 1; // 1不是素数,2和3是素数
    
    // 排除能被2或3整除的数
    if(p % 2 == 0 || p % 3 == 0) return false;

    // 从5开始检查形如 6k ± 1 的数
    for(int i = 5; i * i <= p; i += 6){
        if(p % i == 0 || p % (i + 2) == 0) return false;
    }
    
    return true; // 如果没有找到因子,则p是素数
}

// 去掉一个数的最高位
int reHigh(int r){	
    if(r <= 9) return 0; // 如果只有一个数字,则返回0
    int res = 0, mul = 1;
    while(r > 9){
        res += r % 10 * mul; // 添加最低位数字到结果
        r /= 10; // 移除最低位
        mul *= 10; // 更新乘数
    }
    return res; // 返回去掉最高位后的数
}

int main(){
    // 主循环:遍历所有小于3000的四位数
    for(int i = 1001; i < 3000; i += 2){ // 从1001开始,每次增加2(跳过偶数)
        int t = i;
        bool isFind = true;
        
        // 检查当前数及其去掉最高位后的数是否均为素数
        while(t){
            if(!isPrime(t)){
                isFind = false;
                break; // 如果发现任何一个数不是素数,则退出循环
            }
            t = reHigh(t); // 去掉最高位
        }
        
        // 如果所有去掉最高位后的数均为素数,则输出原始数
        if(isFind) cout << i << endl;
    } 

    return 0; // 程序结束
}

欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》

问题:1258 - 求一个三位数

类型:自定义函数、简单循环


题目描述:

求这样一个三位数,该三位数等于其每位数字的阶乘之和, 即
abc=a!+b!+c!。n! 表示 n 的阶乘, n!=1×2×3×⋯×n,如:5!=1×2×3×4×5)

输入:

输出:

输出这个数。

在这里插入图片描述


1.分析问题

  1. 已知:所有的三位数。
  2. 未知:找出符合条件的数。
  3. 关系:该三位数等于其每位数字的阶乘之和。

2.定义变量

	//二、定义变量(已知、未知、关系) 
	int g,s,b;

3.输入数据

无。

4.数据计算

  • jc 函数:计算一个整数的阶乘。
    • 输入参数 t 表示要计算阶乘的数。
    • 使用一个循环来计算阶乘。
    • 返回阶乘的结果。
int jc(int t){
	int res=1;
	while(t>1){
		res*=t;
		--t;
	}
	return res;
}
  • 遍历从100到999的所有三位数。
    • 对于每个数 i,获取个位、十位和百位上的数字。
    • 计算每一位数字的阶乘。
    • 检查该数是否等于各位数字的阶乘之和。
    • 如果条件满足,则输出该数,并结束循环。
//四、根据关系计算
	for(int i=100;i<1000;++i){
		
		g=i%10;
		s=i/10%10;
		b=i/100;
		
		g=jc(g);
		s=jc(s);
		b=jc(b);
		
		//五、输出未知
		if(i==g+s+b){
			cout<<i;
			break;
		}
	} 

完整代码如下:

#include<bits/stdc++.h>
using namespace std;

// 计算阶乘的函数
int jc(int t){
    int res = 1;
    while (t > 1) {
        res *= t;
        --t;
    }
    return res;
}

int main(){
    // 一、分析问题
    // 已知:所有的三位数。
    // 未知:找出符合条件的数。
    // 关系: 该三位数等于其每位数字的阶乘之和。

    // 二、定义变量(已知、未知、关系)
    int g, s, b; // 个位、十位、百位上的数字

    // 三、输入已知
    // 四、根据关系计算
    for (int i = 100; i < 1000; ++i) { // 遍历所有的三位数
        g = i % 10; // 获取个位数字
        s = i / 10 % 10; // 获取十位数字
        b = i / 100; // 获取百位数字

        // 计算每一位数字的阶乘
        g = jc(g);
        s = jc(s);
        b = jc(b);

        // 五、输出未知
        if (i == g + s + b) { // 如果该数等于各位数字的阶乘之和
            cout << i; // 输出该数
            break; // 找到一个符合条件的数后,结束循环
        }
    }

    return 0; // 程序结束
}

欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》

问题:1140 - 亲密数对

类型:自定义函数


题目描述:

键盘输入 N ,N 在 2 至 2000 之间,求 2 至 N 中的亲密数对,就是 A 的因子和等于 B ,B 的因子和等于 A ,且 A≠B 。
如 48 和 75 是亲密数对。48 的因子和为 2+3+4+6+8+12+16+24=75 ,而 75 的因子和为 3+5+15+25=48 。

输入:

只有一行,为一个整数 N ( 2≤N≤2000 )

输出:

输出若干行,每行两个整数(用一个空格隔开)。

样例1:

输入:

200

输出:

48 75
75 48
140 195
195 140

样例2:

输入:

150

输出:

48 75
75 48

在这里插入图片描述


1.分析问题

  1. 已知:一个整数N ,N 在 2 至 2000 之间;
  2. 未知:求 2 至 N 中的亲密数对;
  3. 关系:A 的因子和等于 B ,B 的因子和等于 A ,且 A≠B 。

2.定义变量

  • n表示输入的最大值,t用于临时存储因子和。
	//二、定义变量(已知、未知、关系)
	int n,t; 

3.输入数据

  • 输入n的值
	//三、输入已知
	cin>>n;

4.数据计算

  • 定义了一个名为sumYz的函数,用来计算小于或等于s的所有真因子之和。
    • 函数内部使用一个循环来找到所有的因子,并累加它们的值。
    • 如果一个因子的平方等于s,说明这个因子被重复计算了两次,需要减去一次。
    • 返回所有因子的累加和。
int sumYz(int s){
	int res=0;
	
	for(int i=2;i*i<=s;++i){
		if(s%i==0) res+=i+s/i;
		if(i==s/i) res-=i;
	}
	
	
	return res;
}
  • 使用一个循环遍历从2到n的所有整数。
    • 对于每一个整数i,调用sumYz函数计算它的因子和t。
    • 检查t是否在2到n的范围内,同时检查i是否是t的因子和,并且i不等于t。
    • 如果满足条件,则输出这对亲和数。
	//四、根据关系计算
	for(int i=2;i<=n;++i){
		
		t=sumYz(i);
		//五、输出未知 
		if(t<=n&&sumYz(t)==i&&i!=t) cout<<i<<" "<<t<<endl;
		
	}

完整代码如下:

#include<bits/stdc++.h> // 包含所有标准C++库
using namespace std;

// 计算一个整数s的所有真因子之和
int sumYz(int s){
    int res = 0; // 初始化结果为0
    
    // 遍历所有可能的因子
    for(int i = 2; i * i <= s; ++i){
        if(s % i == 0){ // 如果i是s的一个因子
            res += i + s / i; // 将i及其对应的配对因子加入结果
        }
        if(i == s / i) // 如果i的配对因子与i相同(即s是完全平方数)
            res -= i; // 避免重复计数
    }
    
    return res; // 返回所有真因子之和
}

int main(){
    // 一、分析问题
    // 已知:一个整数N, N在2至2000之间;
    // 未知:求2至N中的亲和数对;
    // 关系: A的因子和等于B,B的因子和等于A,且A≠B。
    
    // 二、定义变量(已知、未知、关系)
    int n, t; // n表示输入的最大值,t用于临时存储因子和
    
    // 三、输入已知
    cin >> n; // 输入n的值
    
    // 四、根据关系计算
    for(int i = 2; i <= n; ++i){
        
        t = sumYz(i); // 计算i的所有真因子之和
        
        // 五、输出未知
        // 检查t是否也在2至n的范围内,并且i和t互为亲和数
        if(t <= n && sumYz(t) == i && i != t)
            cout << i << " " << t << endl; // 输出这对亲和数
    }
    
    return 0; // 主函数结束
}

欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》

问题:1149 - 回文数个数

类型:自定义函数、2015江苏省青少年信息学奥林匹克竞赛复赛


题目描述:

一个正整数,正读和反读都相同的数为回文数。

例如22 , 131 , 2442 , 37073 , 6 ,… 所有 1 位数都是回文数。

给出一个正整数 n ( 1≤n≤10000 ),求出 1,2,…,n 之中(包括 1 和 n )的回文数的个数。

输入:

任意给定一个正整数 n ( 0<n≤10000 )

输出:

一个正整数,表示[ 1,n ]之间的回文数的个数。

样例:

输入:

325

输出:

41

在这里插入图片描述


1.分析问题

  1. 已知:一个正整数 n ( 0<n≤10000 );
  2. 未知:求出 1,2,…,n 之中(包括 1 和 n )的回文数的个数;
  3. 关系:一个正整数,正读和反读都相同的数为回文数。

2.定义变量

  • 定义变量n用于存储用户输入的最大值,c用于计数回文数的数量。
	//二、定义变量(已知、未知、关系) 
	int n,c=0;

3.输入数据

  • 使用cin从用户获取输入值n。
	//三、输入已知
	cin>>n;

4.数据计算

  • 判断一个整数h是否为回文数。
    • 初始化t为h的副本,r为0。
    • 使用一个循环反转h的数字。
    • 如果反转后的数字等于原数字,则返回true。
bool isHw(int h){
	int t=h,r=0;
	while(t){
		r=r*10+t%10;
		t/=10;
	}
	
	if(h==r) return true;
	
	return false;
}
  • 使用一个循环从1到n遍历所有整数。
  • 对于每个整数i,如果isHw(i)返回true,则增加计数器c。
	//四、根据关系计算
	for(int i=1;i<=n;++i){
		if(isHw(i)) ++c;
	}

5.输出结果

  • 最后,使用cout输出回文数的总数c。
	//五、输出未知 
	cout<<c;

完整代码如下:

#include<bits/stdc++.h> // 包含所有标准C++库
using namespace std;

// 判断一个整数是否为回文数
bool isHw(int h){
    int t = h, r = 0; // 初始化反转后的数字r为0,t用于存储原始数字的副本
    
    // 反转数字
    while(t){
        r = r * 10 + t % 10; // 反转操作
        t /= 10; // 去除最低位
    }
    
    // 检查原数字和反转后的数字是否相等
    if(h == r) return true; // 如果相等,则是回文数
    
    return false; // 否则不是回文数
}

int main(){
    // 一、分析问题
    // 已知:一个正整数 n ( 0<n≤10000 );
    // 未知:求出 1,2,…,n 之中(包括 1 和 n )的回文数的个数;
    // 关系: 一个正整数,正读和反读都相同的数为回文数。
    
    // 二、定义变量(已知、未知、关系)
    int n, c = 0; // n表示输入的最大值,c用于计数回文数的数量
    
    // 三、输入已知
    cin >> n; // 输入n的值
    
    // 四、根据关系计算
    for(int i = 1; i <= n; ++i){
        if(isHw(i)) ++c; // 如果i是回文数,则增加计数器
    }
    
    // 五、输出未知
    cout << c; // 输出回文数的总个数
    
    return 0; // 主函数结束
}

三、感谢

如若本文对您的学习或工作有所启发和帮助,恳请您给予宝贵的支持——轻轻一点,为文章点赞;若觉得内容值得分享给更多朋友,欢迎转发扩散;若认为此篇内容具有长期参考价值,敬请收藏以便随时查阅。

每一次您的点赞、分享与收藏,都是对我持续创作和分享的热情鼓励,也是推动我不断提供更多高质量内容的动力源泉。期待我们在下一篇文章中再次相遇,共同攀登知识的高峰!

欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/871637.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

二进制安装php

下载php二进制包&#xff1a; 官网地址&#xff1a;https://www.php.net/releases/ PHP: Releaseshttps://www.php.net/releases/在里边可以选择自己要下载的包进行下载&#xff1b; 下载完成后进行解压&#xff1a; tar xvzf php-7.3.12.tar.gz 解压后 进入目录进行预编…

学习yolo+Java+opencv简单案例(三)

主要内容&#xff1a;车牌检测识别&#xff08;什么颜色的车牌&#xff0c;车牌号&#xff09; 模型作用&#xff1a;车牌检测&#xff0c;车牌识别 文章的最后附上我的源码地址。 学习还可以参考我前两篇博客&#xff1a; 学习yoloJavaopencv简单案例&#xff08;一&#xff0…

Cobalt Strike 4.8 用户指南-第二节-用户界面

2.1、概述 Cobalt Strike用户界面分为两部分。界面顶部显示会话或目标的可视化。界面底部显示与你交互的每个 Cobalt Strike 功能或会话的选项卡。可以单击这两个部分之间的区域并根据自己的喜好调整它们的大小。 # 2.2、工具栏 顶部的工具栏提供对常见 Cobalt Strike功能的快…

C/C++实现蓝屏2.0

&#x1f680;欢迎互三&#x1f449;&#xff1a;程序猿方梓燚 &#x1f48e;&#x1f48e; &#x1f680;关注博主&#xff0c;后期持续更新系列文章 &#x1f680;如果有错误感谢请大家批评指出&#xff0c;及时修改 &#x1f680;感谢大家点赞&#x1f44d;收藏⭐评论✍ 前…

LeetCode合并两个有序链表

题目描述&#xff1a; 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 示例 2&#xff1a; 输入&#xff1a;l1 [], l2…

chromedriver下载地址大全(包括124.*后)以及替换exe后仍显示版本不匹配的问题

Chrome for Testing availability CNPM Binaries Mirror 若已经更新了系统环境变量里的chromdriver路径下的exe&#xff0c;仍显示版本不匹配&#xff1a; 则在cmd界面输入 chromedriver 会跳出version verison与刚刚下载好的exe不匹配&#xff0c;则再输入&#xff1a; w…

http连接未释放导致生产故障

凌晨4点运维老大收到报警&#xff08;公司官网页面超时&#xff0c;上次故障因为运维修改nginx导致官网域名下某些接口不可用后&#xff0c;运维在2台nginx服务器上放了检测程序&#xff0c;检测官网页面&#xff09;&#xff0c;运维自己先看了看服务器相关配置&#xff0c;后…

小区物业维修管理系统/小区居民报修系统

摘要 小区物业维修是物业公司的核心&#xff0c;是必不可少的一个部分。在物业公司的整个服务行业中&#xff0c;业主担负着最重要的角色。为满足如今日益复杂的管理需求&#xff0c;各类小区物业维修管理系统也在不断改进。本课题所设计的小区物业维修管理系统&#xff0c;使用…

IPC进程间通信方式及网络通信

一、IPC进程间通信方式 1.共享内存&#xff08;最高效的进程间通信方式&#xff09; 其允许两个或多个进程共享一个给定的存储区&#xff0c;这一段存储区可以被两个或以上的进程映射至自己的地址空间中&#xff0c;一个进程写入共享内存的信息&#xff0c;可以被其他使用这个…

“面试宝典:高频算法题目详解与总结”

干货分享&#xff0c;感谢您的阅读&#xff01; &#xff08;暂存篇---后续会删除&#xff0c;完整版和持续更新见高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09;&#xff09; 备注&#xff1a;引用请标注出处&#xff0c;同时存在的问题请在相关博客留言…

每日掌握一个科研插图·2D密度图|24-08-21

小罗碎碎念 在统计学和数据可视化领域&#xff0c;探索两个定量变量之间的关系是一种常见的需求。为了更深入地理解这种关系&#xff0c;我们可以使用多种图形表示方法&#xff0c;这些方法在本质上是对传统图形的扩展和变体。 散点图&#xff1a;这是最基本的图形&#xff0c…

图算法-贪心策略-最小生成树(prim)和最短路径(dijkstra)

参考来源&#xff1a;和感谢 1.代码随想录 (programmercarl.com) 2.【图-最小生成树-Prim(普里姆)算法和Kruskal(克鲁斯卡尔)算法】https://www.bilibili.com/video/BV1wG411z79G?vd_source0ddb24a02523448baa69b0b871ab50f7 3.【图-最短路径-Dijkstra(迪杰斯特拉)算法】ht…

Vue3学习笔记之插槽

目录 前言 一、基础 (一) 默认插槽 (二) 具名插槽 (三) 作用域插槽 (四) 动态插槽 二、实战案例 前言 插槽&#xff08;Slots&#xff09;&#xff1f; 插槽可以实现父组件自定义内容传递给子组件展示&#xff0c;相当于一块画板&#xff0c;画板就是我们的子组件&…

RabbitMQ发布订阅模式Publish/Subscribe详解

订阅模式Publish/Subscribe 基于API的方式1.使用AmqpAdmin定制消息发送组件2.消息发送者发送消息3.消息消费者接收消息 基于配置类的方式基于注解的方式总结 SpringBoot整合RabbitMQ中间件实现消息服务&#xff0c;主要围绕3个部分的工作进行展开&#xff1a;定制中间件、消息发…

使用select

客户端 服务端 1 #include<myhead.h>2 3 #define SER_PORT 6666 //服务器端口4 #define SER_IP "127.0.0.1" //服务器ip5 6 7 int main(int argc, const char *argv[])8 {9 //创建套接字10 int sfdsocket(AF_INET,SOCK_STREAM,0);11 if(sfd-1)12 …

开源大模型LLaMA架构介绍

大模型相关目录 大模型&#xff0c;包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容 从0起步&#xff0c;扬帆起航。 swift与Internvl下的多模态大模型分布式微调指南&#xff08;附代码和数据&#xff…

思科设备静态路由实验

拓扑及需求 网络拓扑及 IP 编址如图所示&#xff1b;PC1 及 PC2 使用路由器模拟&#xff1b;在 R1、R2、R3 上配置静态路由&#xff0c;保证全网可达&#xff1b;在 R1、R3 上删掉上一步配置的静态路由&#xff0c;改用默认路由&#xff0c;仍然要求全网可达。 各设备具体配置…

前端技巧——复杂表格在html当中的实现

应用场景 有时候我们的表格比较复杂&#xff0c;表头可能到处割裂&#xff0c;我们还需要写代码去完成这个样式&#xff0c;所以学会在原生html处理复杂的表格还是比较重要的。 下面我们来看这一张图&#xff1a; 我们可以看到有些表头项的规格不太一样&#xff0c;有1*1 2*…

Unity Protobuf3.21.12 GC 问题(反序列化)

背景&#xff1a;Unity接入的是 Google Protobuf 3.21.12 版本&#xff0c;排查下来反序列化过程中的一些GC点&#xff0c;处理了几个严重的&#xff0c;网上也有一些分析&#xff0c;这里就不一一展开&#xff0c;默认读者已经略知一二了。 如果下面有任何问题请评论区留言提…

实现 FastCGI

CGI的由来&#xff1a; 最早的 Web 服务器只能简单地响应浏览器发来的 HTTP 请求&#xff0c;并将存储在服务器上的 HTML 文件返回给浏 览器&#xff0c;也就是静态 html 文件&#xff0c;但是后期随着网站功能增多网站开发也越来越复杂&#xff0c;以至于出现动态技 术&…