试题 C: 好数
时间限制
: 1.0s 内存限制: 256.0MB 本题总分:10
分
【问题描述】
一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位
· · ·
)上 的数字是奇数,偶数位(十位、千位、十万位 · · ·
)上的数字是偶数,我们就称 之为“好数”。 给定一个正整数 N
,请计算从
1
到
N
一共有多少个好数。 【输入格式】
一个整数
N
。
【输出格式】
一个整数代表答案。
【样例输入
1
】
24
【样例输出
1
】
7
【样例输入
2
】
2024
【样例输出
2
】
150
【样例说明】
对于第一个样例,
24
以内的好数有
1
、
3
、
5
、
7
、
9
、
21
、
23
,一共
7
个。
【评测用例规模与约定】
对于
10
%
的评测用例,
1
≤
N
≤
100
。
对于
100
%
的评测用例,
1
≤
N
≤
10^
7
运行代码
#include <iostream>
using namespace std;
bool Good(int num) {
int pos = 1;
while (num > 0) {
int digit = num % 10;
if ((pos % 2 == 1 && digit % 2 == 0) || (pos % 2 == 0 && digit % 2 == 1)) {
return false;
}
num /= 10;
pos++;
}
return true;
}
int Count(int n) {
int count = 0;
for (int i = 1; i <= n; i++) {
if (Good(i)) {
count++;
}
}
return count;
}
int main() {
int n;
cin >> n;
cout << Count(n) << endl;
return 0;
}
代码思路
计算从 1 到给定整数 n
范围内的 “好数” 的个数。“好数” 的定义是如果一个整数从低位到高位,奇数位上的数字是奇数,偶数位上的数字是偶数,那么这个数就是 “好数”。
-
Good
函数:判断一个整数是否为 “好数”。num
代表要判断的整数。- 使用
pos
变量记录当前数字的位数位置,初始为 1,表示个位。 - 进入循环,当
num
大于 0 时,每次取num
的最后一位数字digit
(通过num % 10
)。 - 根据
pos
的奇偶性判断digit
是否符合 “好数” 的条件。如果pos
是奇数位且digit
是偶数,或者pos
是偶数位且digit
是奇数,则满足条件;否则不满足条件,直接返回false
。 - 每判断一位数字后,将
num
除以 10(num /= 10
),同时pos
加一,继续判断下一位数字。如果所有位数都满足条件,则返回true
。
- 使用
-
Count
函数:计算从 1 到给定整数n
范围内 “好数” 的个数。n
代表范围的上限。- 使用
count
变量记录 “好数” 的个数,初始为 0。 - 通过循环遍历从 1 到
n
的所有整数。 - 对于每个整数
i
,调用Good
函数判断是否为 “好数”,如果是,则将count
加一。 - 循环结束后,返回
count
作为 “好数” 的个数。
- 使用
-
main
函数:输入一个整数n
,调用Count
函数计算并输出从 1 到n
范围内 “好数” 的个数。读取用户输入的整数n
。调用Count
函数计算 “好数” 的个数输出计算结果。
试题 D: R 格式
时间限制
: 1.0s 内存限制: 256.0MB 本题总分:10
分
【问题描述】
小蓝最近在研究一种浮点数的表示方法:
R
格式。对于一个大于
0
的浮点
数
d
,可以用
R
格式的整数来表示。给定一个转换参数
n
,将浮点数转换为
R
格式整数的做法是: 1. 将浮点数乘以
2
n
; 2. 四舍五入到最接近的整数。
【输入格式】
一行输入一个整数
n
和一个浮点数
d
,分别表示转换参数,和待转换的浮点数。
【输出格式】
【输出格式】
输出一行表示答案:d 用 R
格式表示出来的值。
【样例输入】
2 3.14
【样例输出】
13
【样例说明】
3
.
14
×
2
2
= 12
.
56
,四舍五入后为
13
。
【评测用例规模与约定】
对于
50
%
的评测用例:
1
≤
n
≤
10
,
1
≤
将
d
视为字符串时的长度
≤
15
。
对于
100
%
的评测用例:
1
≤
n
≤
1000
,
1
≤
将
d
视为字符串时的长度 ≤ 1024
;保证
d
是小数,即包含小数点。
运行代码
#include <iostream>
#include <cmath>
using namespace std;
int convert(int n, double d) {
return round(d * pow(2, n));
}
int main() {
int n;
double d;
cin >> n >> d;
cout << convert(n, d) << endl;
return 0;
}
上述这个代码只可以通过部分数据
使用高精度乘法
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// 乘法函数
vector<int> multiply(vector<int>& A, int b) {
vector<int> result;
int carry = 0;
for (int i = 0; i < A.size() || carry; ++i) {
int sum = carry;
if (i < A.size()) sum += A[i] * b;
result.push_back(sum % 10);
carry = sum / 10;
}
while (result.size() > 1 && result.back() == 0) result.pop_back();
return result;
}
int main() {
int n;
string str;
cin >> n >> str;
int dot= str.find('.');
int d = str.size() - dot - 1;
vector<int> num;
for (int i = str.size() - 1; i >= 0; --i) {
if (str[i]!= '.') num.push_back(str[i] - '0');
}
vector<int> res = num;
for (int i = 1; i <= n; ++i) res = multiply(res, 2);
if (res[d - 1] > 4) res[d]++;
for (int i = res.size() - 1; i >= d; --i) cout << res[i];
return 0;
}
代码思路
读取一个包含小数点的数字字符串,将其转换为整数数组表示,然后对这个数字进行 n
次乘以 2 的操作,并根据小数点后的特定位置数字进行四舍五入,最后输出四舍五入后的结果。
-
multiply
函数:实现两个数的模拟乘法运算,其中一个数用整数向量A
表示,另一个数是整数b
。- 最后返回乘法运算的结果向量。
- 循环结束后,如果
result
向量末尾有多余的 0,则去除这些多余的 0(保证结果的简洁性)。 - 更新进位值
carry
为sum
除以 10。 - 将
sum
对 10 取余得到当前位的结果数字,存入result
向量中。 - 对于每一位,计算当前位的和
sum
,等于进位值carry
,如果当前索引小于A
的大小,则加上当前位数字与b
的乘积。 - 遍历
A
的每一位或者当有进位时继续循环。 - 创建一个结果向量
result
和一个进位变量carry
初始化为 0。
-
main
函数- 输入部分:读取一个整数
n
和一个字符串str
,代表要进行的乘法次数和初始数字字符串。通过str.find('.')
找到字符串中小数点的位置,存入变量dot
,并计算出小数点后的位数d
。 - 转换部分:创建一个整数向量
num
,通过从字符串末尾开始遍历,将非小数点的字符转换为数字并存入num
中。初始化结果向量res
为num
。 - 乘法和四舍五入部分:通过循环
n
次调用multiply
函数对res
进行乘以 2 的操作。根据小数点后特定位置的数字判断是否需要四舍五入,如果res[d - 1]
(小数点后一位)大于 4,则将res[d]
(小数点后要输出的第一位)加 1。 - 输出部分:从结果向量
res
的末尾开始,输出从d
位置开始到末尾的数字,即四舍五入后的结果。
- 输入部分:读取一个整数