片头
嗨~小伙伴们,咱们继续攻克填空题,先把5分拿到手~
第1题 数位递增的数
这道题,需要我们计算在整数 1 至 n 中有多少个数位递增的数。
什么是数位递增的数呢?一个正整数如果任何一个数位不大于右边相邻的数位。比如:1234是一个数位递增的数;4321则不是。
解题思路:我们可以把1~n个数全部转化为字符串类型。用另外一个字符串类型的变量s来保存。再对当前这个字符串进行排序(排升序)。如果二者相同,那么该数是数位递增的数。
#include <bits/stdc++.h> // 包含所有标准库头文件
using namespace std; // 使用标准命名空间
int main()
{
int n;
cin >> n; // 从标准输入读取一个整数n
int ans = 0; // 初始化计数器ans为0,用于统计符合条件的数字个数
for(int i = 1; i <= n; i++) // 遍历从1到n的每个数字
{
string s = to_string(i); // 将当前数字i转换为字符串形式
string s1 = s; // 创建字符串s的副本s1
sort(s1.begin(), s1.end()); // 对s1中的字符按升序排序
if(s == s1) ans++; // 如果原字符串s与排序后的s1相同,说明数字是升序排列的
}
cout << ans << endl; // 输出符合条件的数字个数
return 0;
}
第2题 数位和
这道题目很简单,将1~1000所有数字的数位和算出来,累加到变量SUM中,就可以了。
#include <iostream>
using namespace std;
//求数位和
int get_sum(int x){
int temp = x;
int sum = 0;
while(temp != 0){
int r = temp % 10;
sum += r;
temp /= 10;
}
return sum;
}
int main()
{
int SUM = 0;
for(int i = 1; i<= 1000; i++)
{
SUM += get_sum(i);
}
cout << SUM << endl;
return 0;
}
第3题 数位比较
这道题,是给定我们区间范围,计算满足数字的数位上的 0 的个数要大于数位上的 1 的个数。
#include <iostream>
using namespace std;
int Func(int x)
{
int temp = x; // 创建临时变量保存x的值
int num1 = 0, num2 = 0; // num1统计0的个数,num2统计1的个数
while(temp != 0) { // 循环处理每一位数字
if(temp % 10 == 0) num1++; // 如果当前位是0,num1加1
if(temp % 10 == 1) num2++; // 如果当前位是1,num2加1
temp /= 10; // 去掉已处理的最低位
}
if(num1 > num2) return 1; // 如果0比1多,返回1
else return 0; // 否则返回0
}
int main()
{
int L, R; // 定义区间端点变量
cin >> L >> R; // 输入区间范围[L, R]
int ans = 0; // 初始化计数器
for(int i = L; i <= R; i++) { // 遍历区间内每个数字
if(Func(i) == 1) ans++; // 如果满足条件,计数器加1
}
cout << ans << endl; // 输出结果
return 0;
}
第4题 最小数位和
这道题,虽然数据量比较大,但是我们不要被题目唬住了。
解题思路:①可以定义8行8列的二维数组存储64个数据。
int a[8][8] = {
{454771,329157,801601,580793,755604,931703,529875,361797},
{604358,529564,574776,821517,195563,688516,223321,607845},
{284772,603562,543328,707484,533688,380468,233733,257995},
{896582,670074,912386,702393,722092,834842,126346,606526},
{376981,910643,413754,945725,817853,651778,350775,676550},
{316935,487808,939526,900568,423326,298936,927671,539773},
{136326,717022,886675,466684,436470,558644,267231,902422},
{743580,857864,529622,320921,595409,486860,951114,558787}
};
②题目问我们数位和最小的数,咱们先实现一个求数位和的函数。
//求数位和
int get_sum(int a) {
int sum = 0;
int temp = a;
while (temp != 0) {
int r = temp % 10;
sum += r;
temp /= 10;
}
return sum;
}
接着我们可以在main函数中调用get_sum函数。
定义变量min,初始值为INT_MAX(需要引用头文件 <climits>,但是 <bits/stdc++.h> 已经包含了)。
从第1行第1列,也就是从第1个元素(a[0][0])开始遍历,依次计算每个数的数位和,保存到变量d中。如果当前的数位和d<min,那么将d赋给min (min = d),同时用另一个变量num保存当前的数。
int min = INT_MAX; // 初始化最小和为最大整数值
int num = 0; // 存储数字和最小的那个数
int d = 0; // 临时存储数字和
// 遍历二维数组
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
d = get_sum(a[i][j]); // 计算当前数的数字和
if (d < min) { // 如果比当前最小值小
min = d; // 更新最小值
num = a[i][j]; // 更新对应的数
}
}
}
最后输出数位和最小的数
cout << num << endl; // 输出结果
ok,本道题的完整代码如下:
#include <bits/stdc++.h>
using namespace std;
//求数位和
int get_sum(int a){
int sum = 0;
int temp = a;
while(temp != 0){
int r = temp % 10;
sum += r;
temp /= 10;
}
return sum;
}
int main()
{
int a[8][8] = {
{454771,329157,801601,580793,755604,931703,529875,361797},
{604358,529564,574776,821517,195563,688516,223321,607845},
{284772,603562,543328,707484,533688,380468,233733,257995},
{896582,670074,912386,702393,722092,834842,126346,606526},
{376981,910643,413754,945725,817853,651778,350775,676550},
{316935,487808,939526,900568,423326,298936,927671,539773},
{136326,717022,886675,466684,436470,558644,267231,902422},
{743580,857864,529622,320921,595409,486860,951114,558787}
};
int min = INT_MAX; // 初始化最小和为最大整数值
int num = 0; // 存储数字和最小的那个数
int d = 0; // 临时存储数字和
// 遍历二维数组
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
d = get_sum(a[i][j]); // 计算当前数的数字和
if (d < min) { // 如果比当前最小值小
min = d; // 更新最小值
num = a[i][j]; // 更新对应的数
}
}
}
cout << num << endl; // 输出结果
return 0;
}
第5题 数位和相等
题目让我们求第23个数位和相等的正整数,数位和相等:一个正整数转化成二进制与转换成八进制后所有数位的数字之和相等。
定义变量count(计数器),表示满足条件的第几个数;定义变量i,初始值为1,从1开始检查数字。
没有给定循环范围,因此我们采用while循环。因为求第23个数位和相等的数,如果count从0开始,那么到22结束;如果count从1开始,那么到23结束。
int i = 1; // 从1开始检查数字
int count = 0; // 计数器,记录满足条件的数字个数
while(count < 23) //count的取值范围: 0~22,总共23个数
{
if(S(i)) count++; // 如果i满足条件,计数器加1
i++; // 检查下一个数字
}
当count==23时,退出while循环。但是此时 i 已经自增,因此需要输出 i-1。
// 注意:此时i已经自增过了,所以要输出i-1
cout << i-1 << endl;
接下来我们需要实现S函数,判断1个数的二进制和八进制的数位和是否相同。
int S(int N) {
if (N <= 0) return 0; // 处理非正整数
int sum2 = 0, sum8 = 0; // sum2存储二进制和,sum8存储八进制和
int temp = N; // 临时变量保存N的值
//计算二进制各位和
while (temp != 0)
{
int r = temp % 2; // 取二进制最后一位
sum2 += r; // 累加到sum2
temp /= 2; // 去掉已处理的最后一位
}
temp = N; // 重置temp为原始值
//计算八进制各位和
while (temp != 0)
{
int ge = temp % 8; // 取八进制最后一位
sum8 += ge;
temp /= 8;
}
if (sum2 == sum8) return 1; // 和相等返回1
else return 0; // 不等返回0
}
欧克啦,本题的完整代码如下:
#include <iostream>
using namespace std;
int S(int N) {
if (N <= 0) return 0; // 处理非正整数
int sum2 = 0, sum8 = 0; // sum2存储二进制和,sum8存储八进制和
int temp = N; // 临时变量保存N的值
//计算二进制各位和
while (temp != 0)
{
int r = temp % 2; // 取二进制最后一位
sum2 += r; // 累加到sum2
temp /= 2; // 去掉已处理的最后一位
}
temp = N; // 重置temp为原始值
//计算八进制各位和
while (temp != 0)
{
int ge = temp % 8; // 取八进制最后一位
sum8 += ge;
temp /= 8;
}
if (sum2 == sum8) return 1; // 和相等返回1
else return 0; // 不等返回0
}
int main()
{
int i = 1; // 从1开始检查数字
int count = 0; // 计数器,记录满足条件的数字个数
while (count < 23) //count的取值范围: 0~22,总共23个数
{
if (S(i)) count++; // 如果i满足条件,计数器加1
i++; // 检查下一个数字
}
// 注意:此时i已经自增过了,所以要输出i-1
cout << i - 1 << endl;
return 0;
}
第6题 数位计数
这道题,很简单。统计1个数一共有多少个数位。n的范围比较大,因此我们可以用 long long 来定义。
#include <iostream>
using namespace std;
typedef long long ll;
ll get_count(ll x){
ll temp = x;
ll count = 0;
while(temp != 0)
{
temp = temp / 10;
count++; //统计数位个数
}
return count;
}
int main()
{
ll n;
cin >> n;
ll ret = get_count(n);
cout << ret << endl;
return 0;
}
第7题 数位和
首先,题目给定范围:①质数,因此我们需要实现判断是否为质数的函数; ②计算质数的各个数位之和,判断是否等于23。我们需要实现计算数位和的函数。
判断是否为质数的代码如下:
//判断是否为质数
bool is_prime(int x)
{
//这里必须是 i < sqrt(x), 不然编译报错
for(int i = 2; i < sqrt(x) ; i++)
{
if(x % i == 0) return 0; //不是质数,返回0
}
return 1;//只能被 1 和本身整除,是质数,返回1
}
需要额外注意:质数判断应从2开始,且只需检查到即可
计算数位和的函数如下:
//计算数位和
int get_sum(int x)
{
int temp = x;
int sum = 0;
while (temp != 0)
{
int r = temp % 10;
sum += r;
temp /= 10;
}
return sum;
}
最后在main函数里面调用这2个函数即可。
//计数器,统计满足条件的数的个数
int cnt = 0;
for(int i = 3; i <= 1000000; i++)
{
//如果该数为质数并且数位之和为23,计数器+1
if(is_prime(i) && get_sum(i) == 23) cnt++;
}
cout << cnt <<endl; //输出结果
欧克啦,本题完整代码如下:
#include <bits/stdc++.h>
using namespace std;
//判断是否为质数
bool is_prime(int x)
{
//这里必须是 i < sqrt(x), 不然编译报错
for(int i = 2; i < sqrt(x) ; i++)
{
if(x % i == 0) return 0;
}
return 1;
}
//计算数位和
int get_sum(int x)
{
int temp = x;
int sum = 0;
while(temp != 0)
{
int r = temp % 10;
sum += r;
temp /= 10;
}
return sum;
}
int main()
{
//计数器,统计满足条件的数的个数
int cnt = 0;
for(int i = 3; i <= 1000000; i++)
{
//如果该数为质数并且数位之和为23,计数器+1
if(is_prime(i) && get_sum(i) == 23) cnt++;
}
cout << cnt <<endl; //输出结果
return 0;
}
第8题 倍数
这道题很简单,代码如下:
#include <iostream>
using namespace std;
int main()
{
int cnt = 0;
for(int i = 1; i <= 2020; i++){
if(i % 4 == 0 && i % 6 == 0) cnt++;
}
cout << cnt << endl;
return 0;
}
第9题 约数
代码如下:
#include <iostream>
using namespace std;
int main()
{
int cnt = 0;
for (int i = 1; i <= 2020; i++) {
if (2020 % i == 0) cnt++;
}
cout << cnt << endl;
return 0;
}
第10题 公约数
代码如下:
#include <iostream>
using namespace std;
int main()
{
int cnt = 0;
for (int i = 1; i <= 2020; i++) {
if (2020 % i == 0 && 3030 % i == 0) cnt++;
}
cout << cnt << endl;
return 0;
}
第11题 约数个数
代码如下:
#include <iostream>
using namespace std;
int main()
{
int n = 1200000;
int ans = 0;
for (int i = 1; i <= n; i++) {
if (n % i == 0) ans++;
}
cout << ans;
return 0;
}
片尾
今天我们巩固了填空题基础,希望看完这篇文章对友友们有所帮助!!!
求点赞收藏加关注!!!
谢谢大家!!!