测评网站:信息学奥赛一本通(C++版)在线评测系统
1150:求正整数2和n之间的完全数
【题目描述】
求正整数2和n之间的完全数(一行一个数)。
完全数:因子之和等于它本身的自然数,如6=1+2+3
【题目分析】
方法1:从[1,n)枚举所有的数,如果能被n整除进行累加,最后判断累加和是否等于n,如果等于就为完全数 时间复杂度为O(n*n)
方法2:累加和为1,从2枚举到sqrt(n)(不包含n开平方),如果能被n整除,将该数和商进行累加,最后判断n能否被sqrt整除,能进行累加,最后判断累加和是否等于n,如果等于就为完全数,时间复杂度为O(n*sqrt(n))
1151:素数个数
【题目描述】
编程求2-n(n为大于等于2的正整数)中有多少个素数。
【题目分析】
判断素数函数编写:如果n为2时,返回true,否则枚举i为2—sqrt(n)的所有数,如果n能够被i整除返回false,否则返回true; 时间复杂度为O(n*sqrt(n))
1152:最大数max(x,y,z)
【题目描述】
【题目分析】
求最大数的函数编写:
方法1:如果a>b,判断a>c,最大数为a,否则最大数为c
否则 判断b>c,最大数为b,否则最大数为c
方法2:设置maxn为0,依次判断a、b、c是否大于maxn,大于情况下将相应值赋给maxn
1153:绝对素数
【题目描述】
如果一个自然数是素数,且它的数字位置经过对换后仍为素数,则称为绝对素数,例如13。试求出所有二位绝对素数。
【题目分析】
枚举所有的二位数i从 10——99,对换后的数为j=i%10*10+i/10,当i和j都为素数时,说明i为绝对素数。
判断素数函数编写:如果n为2时,返回true,否则枚举i为2—sqrt(n)的所有数,如果n能够被i整除返回false,否则返回true; 时间复杂度为O(n*sqrt(n))
优化方向:两位数交换位置还是两位数,可以使用bool book[100] 记录10—99的绝对素数,在进行枚举判断时,先判断book相应元素是否为1,不为1时,进行i的绝对素数判断,成立将book[i] 和 book[j] 都赋值为1;最后依次检查book数组进行数据输出即可。
1154:亲和数
【题目描述】
自然数a的因子是指能整除a的所有自然数,但不含a本身。例如12的因子为:1,2,3,4,6。若自然数a的因子之和为b,而且b的因子之和又等于a,则称a,b为一对“亲和数” 。求最小的一对亲和数(a<>b)。
【题目分析】
从2开始枚举i,计算i的因子和为j,在判断j的因子和是否为i,如果成立,i和j为一对亲和数,要保证i≠j
因子和函数的编写:从[1,n)枚举所有的数,如果能被n整除进行累加
1155:回文三位数
【题目描述】
如果一个数从左边读和从右边读都是同一个数,就称为回文数。例如6886就是一个回文数,求出所有的既是回文数又是素数的三位数。
【题目分析】
从100——999开始枚举i,判断i是否既是回文数(个位数等于千位数 i%10==i/10/10),又是素数
判断素数函数编写:如果n为2时,返回true,否则枚举i为2—sqrt(n)的所有数,如果n能够被i整除返回false,否则返回true;
1156:求π的值
【题目描述】
【题目分析】
泰勒展开式
计算第i项(从0开始,每次加1)的数值m,如果m>=1e-6,累加到pi,最后输出6*pi的值
计算第i项的数值函数:
return
1157:哥德巴赫猜想
【题目描述】
哥德巴赫猜想的命题之一是:大于6 的偶数等于两个素数之和。编程将6~100所有偶数表示成两个素数之和。
【题目分析】
朴素算法
从6——100开始枚举i,每次加2,将i传入函数分解为素数之和并输出
偶数分解素数函数编写:枚举1-i的数j,如果j为素数,i-j也为素数,则输出结果,结束循环
判断素数函数编写:如果n为1 或者 0 返回false,如果n为2时,返回true,否则枚举i为2—sqrt(n)的所有数,如果n能够被i整除返回false,否则返回true;
优化算法
先打表寻找1-100之间的素数(素数筛选法素数筛选法_Nightmare004的博客-CSDN博客_素数筛选法),并记录在数组bool a[100]中,如果a[n]==1说明n为素数,从6——100开始枚举i,每次加2,将i传入函数分解为素数之和并输出
偶数分解素数函数编写:枚举j从1—i-1,如果a[j] && a[i-j] 则输出结果,跳出循环
1397:简单算术表达式求值
【题目描述】
两位正整数的简单算术运算(只考虑整数运算),算术运算为:
+,加法运算; -,减法运算; *,乘法运算; /,整除运算; %,取余运算。
算术表达式的格式为(运算符前后可能有空格): 运算数 运算符 运算数
请输出相应的结果。
【题目分析】
顺序 读入运算数和运算符到字符数组,使用函数atoi将运算数 字符数组转化为整数,根据运算符的不同进行计算。
char x;
int cnt = 0;
while (x = getchar(), (x >= '0' && x <= '9') || x == ' ') {
a[cnt++] = x;
}
c = x, cnt = 0;
while (x = getchar(), (x >= '0' && x <= '9') || x == ' ') {
b[cnt++] = x;
}
1398:短信计费
【题目描述】
用手机发短信,一条短信资费为0.1元,但限定一条短信的内容在70个字以内(包括70个字)。如果你一次所发送的短信超过了70个字,则会按照每70个字一条短信的限制把它分割成多条短信发送。假设已经知道你当月所发送的短信的字数,试统计一下你当月短信的总资费。
【题目分析】
读入短信数量,根据短信数量依次读入短信字数,将每条短信进行资费统计记和,最终输出总资费。
每条短信资费D计算函数:return D=ceil(n/10)*0.1(ceil函数是向上取整)
1399:甲流病人初筛
【题目描述】
目前正是甲流盛行时期,为了更好地进行分流治疗,医院在挂号时要求对病人的体温和咳嗽情况进行检查,对于体温超过37.5度(含等于37.5度)并且咳嗽的病人初步判定为甲流病人(初筛)。现需要统计某天前来挂号就诊的病人中有多少人被初筛为甲流病人。
【题目分析】
对于体温超过37.5度(含等于37.5度)并且咳嗽的病人初步判定为甲流病人
体温使用double变量,咳嗽使用bool,病人姓名使用字符数组(cin读入cout输出/sanf读入printf输出 %s)或者字符串(cin读入cout输出)
1400:统计单词数
【题目描述】
一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意:匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同(参见样例1),如果给定单词仅是文章中某一单词的一部分则不算匹配(参见样例2)。
【题目分析】
方法1(整体比较):使用二维字符数组存储文章内容,使用字符数组存储匹配单词,使用strlwr将字符数组和文章单词转化为小写,使用strcmp进行比较,如果相同计数加1.
方法2(局部比较):使用字符数组a存储文章内容,使用字符数组b存储匹配单词,使用i指向文章字符数组头,j指向匹配单词头,外层循环条件 i<lena, 内层循环条件a[i]!=‘ ’&&j<lenb 如果a[i]==b[j] i++,j++ 当退出循环时,当a[i]==‘ ’&&j==lenb说明匹配,否则不匹配。重复执行直到a[i] 指向空格,再重复执行直到a[i] 指向字母,j=0.(a[i]和b[j]的匹配要将两者转化为大写或者小写 toupper tolower),判断一个字符是否是字母可以使用函数isalpha()
1401:机器翻译
【题目描述】
小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章。
这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换。对于每个英文单词,软件会先在内存中查找这个单词的中文含义,如果内存中有,软件就会用它进行翻译;如果内存中没有,软件就会在外存中的词典内查找,查出单词的中文含义然后翻译,并将这个单词和译义放入内存,以备后续的查找和翻译。
假设内存中有M个单元,每单元能存放一个单词和译义。每当软件将一个新单词存入内存前,如果当前内存中已存入的单词数不超过M−1,软件会将新单词存入一个未使用的内存单元;若内存中已存入M 个单词,软件会清空最早进入内存的那个单词,腾出单元来,存放新单词。
假设一篇英语文章的长度为N个单词。给定这篇待译文章,翻译软件需要去外存查找多少次词典?假设在翻译开始前,内存中没有任何单词。
【题目分析】
设置外存查找计数ans,读入一个数据进行内存查找,如果不在内存中返回true,ans加一
内存查找函数:定义一个整型数组a和cnt计数,用来记录内存数据和需要覆盖的内存数据索引,读入一个数据x,枚举内存数据,如果匹配,返回false,枚举完成还不在内存中,a[cnt%n]=x;cnt++;返回true
1402:Vigenère密码
【题目描述】
【题目分析】
定义两个字符数组s1和s2,分别记录密钥和密文,循环 lens1<lens2 ,strcat(s1,s1);将密钥的长度增长到和密文一样,将密钥和密文都转化为大写字母strupr(),枚举密钥和密文的字符使用解密函数,对数据进行一一解密,并将结果显示出来。
解密函数:明文字符为a,密钥字符为b,密文字符为c(加密过程:(a-‘A’+(b-‘A’))%26+'A'),解密过程:(c-'A'+26-(b-'A'))-'A'
1403:素数对
【题目描述】
两个相差为2的素数称为素数对,如5和7,17和19等,本题目要求找出所有两个数均不大于n的素数对。
【题目分析】
枚举小于等于n的所有整数i,判断i和i+2是否同时是素数,如果是输出i和i+2
判断素数函数编写:如果n为1 或者 0 返回false,如果n为2时,返回true,否则枚举i为2—sqrt(n)的所有数,如果n能够被i整除返回false,否则返回true;
1404:我家的门牌号
【题目描述】
我家住在一条短胡同里,这条胡同的门牌号从1开始顺序编号。若其余各家的门牌号之和减去我家门牌号的两倍,恰好等于n,求我家的门牌号及总共有多少家。数据保证有唯一解。
【题目分析】
我家的门牌号为j,总共有i家(1<=j<=i) 则需判断 (1+i)*i/2-3*j==n即可,从1开始循环枚举i,根据每一个i,枚举j从1-i,如果满足条件返回i和j(可定义全局变量进行数据的记录)。
1405:质数的和与积
【题目描述】
两个质数的和是S,它们的积最大是多少?
【题目分析】
对于s可以分解为i和s-i,其中i从s/2—2(因为两个数越靠近乘积越大),判断i和s-i是否同时为质数即可
质数的判断:如果n为1 或者 0 返回false,如果n为2时,返回true,否则枚举i为2—sqrt(n)的所有数,如果n能够被i整除返回false,否则返回true;
1406:单词替换
【题目描述】
输入一个字符串,以回车结束(字符串长度≤200)。该字符串由若干个单词组成,单词之间用一个空格隔开,所有单词区分大小写。现需要将其中的某个单词替换成另一个单词,并输出替换之后的字符串。
【题目分析】
使用二维字符数组a记录字符串,使用字符数组b[0]记录需要替换的单词,b[1]记录替换成的单词,枚举a[i],使用strcmp匹配a[i] 与 b[0],使用strcpy将b[1]赋值给a[i]
1407:笨小猴
【题目描述】
【题目分析】
使用桶排序的基本思想,使用整型数组cnt[26]记录每个字母出现的次数,读入一个字母c,cnt[c-'a'],循环遍历cnt找出最大值maxn和最小值minn,判断maxn-minn是否为质数
质数的判断函数:如果n为1 或者 0 返回false,如果n为2时,返回true,否则枚举i为2—sqrt(n)的所有数,如果n能够被i整除返回false,否则返回true;
1408:素数回文数的个数
【题目描述】
求11到n之间(包括n),既是素数又是回文数的整数有多少个。
【题目分析】
素数的判断函数:如果n为1 或者 0 返回false,如果n为2时,返回true,否则枚举i为2—sqrt(n)的所有数,如果n能够被i整除返回false,否则返回true;
回文数的判断:如果数字m<100,只需要判断m%10==m/10,否则,只需要判断m/10/10==m%10
1409:判决素数个数
【题目描述】
输入两个整数X和Y,输出两者之间的素数个数(包括X和Y)。
【题目分析】
素数的判断函数:如果n为1 或者 0 返回false,如果n为2时,返回true,否则枚举i为2—sqrt(n)的所有数,如果n能够被i整除返回false,否则返回true;
1410:最大质因子序列
【题目描述】
【题目分析】
最大质因子函数,对于一个数i,枚举i—2为j,如果i%j==0&&j为质数,则j为最大质因子
质数的判断函数:如果n为1 或者 0 返回false,如果n为2时,返回true,否则枚举i为2—sqrt(n)的所有数,如果n能够被i整除返回false,否则返回true;
1411:区间内的真素数
【题目描述】
找出正整数M和N之间(N不小于M)的所有真素数。
真素数的定义:如果一个正整数P为素数,且其反序也为素数,那么P就为真素数。
例如,11,13均为真素数,因为11的反序还是为11,13的反序为31也为素数。
【题目分析】
一个数的反序:
int i = 85264, j = 0;
while (i != 0) {
j = j * 10 + i % 10;
i /= 10;
}
cout << j;
质数的判断函数:如果n为1 或者 0 返回false,如果n为2时,返回true,否则枚举i为2—sqrt(n)的所有数,如果n能够被i整除返回false,否则返回true;
1412:二进制分类
【题目描述】
【题目分析】
使用变量cntA和cntB记录A类数和B类数的个数,统计一个数表示成二进制数中0和1的个数
int i = 85264, a0 = 0, a1 = 0;
while (i != 0) {
if (i % 2 == 0) a0++;
else a1++;
i /= 2;
}
如果a1>a0 则cntA++,否则cntB++;
1413:确定进制
【题目描述】
【题目分析】
枚举进制i,对于i进制将p q r转化为十进制,计算结果是否成立。
将一个数m根据进制B转化为十进制数的函数:取m的每一位数乘以B的对应次幂即可
int btod(int m, int B) {
int n = m % 10;
m /= 10;
while (m != 0) {
n += m % 10 * B;
m /= 10;
B *= B;
}
return n;
}