1389. 数据分析
问题描述
某军事单位采用特殊加密方法传递信息。传递一个整数n(10位以内),其长度代表第一个数字信息,将n的偶数位相加得到第二个数字信息。要求编写程序从n中获取这两个数字信息。
解题思路
- 读取输入:接收一个整数n。
- 计算位数:初始化一个计数器,循环除以10直到n变为0,得到位数。
- 计算偶数位之和:在计算位数的同时,判断每一位是否为偶数,如果是则累加。
- 输出结果:输出位数和偶数位之和。
代码实现
cpp
#include <iostream>
using namespace std;
int main() {
long long n;
cin >> n;
int digits = 0;
int sum = 0;
while (n > 0) {
int digit = n % 10;
digits++;
if (digit % 2 == 0) {
sum += digit;
}
n /= 10;
}
cout << digits << " " << sum << endl;
return 0;
}
代码解析
- 使用
long long
类型存储输入的n,因为n可能高达10^9。 - 初始化
digits
变量记录位数,sum
变量记录偶数位之和。 - 使用
while
循环处理n的每一位:n % 10
获取最后一位数字。digits++
计数位数。- 判断该位是否为偶数,是则加到
sum
中。 n /= 10
去掉最后一位。
- 循环结束后,
digits
存储位数,sum
存储偶数位之和。 - 最后按要求格式输出结果。
1750. 有0的数
问题描述
求出1到n(n≤999)之间含有数字0的数的个数。
解题思路
- 遍历数字:从1遍历到n。
- 分解每个数:对于每个数,分解成个位、十位和百位。
- 检查每一位:检查每一位是否为0。
- 计数:如果一个数的任何一位是0,则计数器加1。
代码实现
cpp
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int count = 0;
for (int i = 1; i <= n; i++) {
int num = i;
bool hasZero = false;
while (num > 0) {
if (num % 10 == 0) {
hasZero = true;//存在0位
break;
}
num /= 10;
}
if (hasZero) {
count++;
}
}
cout << count << endl;
return 0;
}
代码解析
- 读取输入n。
- 使用
for
循环遍历1到n的所有数。 - 对于每个数i:
- 将i赋值给临时变量
num
。 - 使用
while
循环检查num
的每一位:- 如果当前位(
num % 10
)等于0,设置hasZero
为true并跳出循环。 - 否则,将
num
除以10,检查下一位。
- 如果当前位(
- 如果
hasZero
为true,增加计数器count
。
- 将i赋值给临时变量
- 循环结束后,输出
count
,即包含0的数的个数。 - 这种方法的时间复杂度仍然是O(n log n),因为对每个数都要检查其每一位。
- 这个实现没有使用单独的函数,而是将所有逻辑都放在main函数中,符合不使用函数的要求。
- 对于n≤999的情况,这种方法是足够高效的。如果n的范围更大,可能需要考虑更优化的算法。
1962. 数值计算
问题描述
给出一个不多于5位的非负整数(非0结尾),要求:
- 求出它是几位数
- 分别输出每一位数字
- 按逆序输出各位数字
解题思路
- 计算位数:使用循环除以10,直到商为0,计数得到位数。
- 输出每一位数字:利用整数除法和取模运算,从高位到低位输出每一位。
- 逆序输出:直接使用取模运算从低位到高位输出。
代码实现
cpp
#include <iostream>
#include <cmath>
using namespace std;
int main() {
int num, originalNum; // 声明变量存储输入的数字和原始数字
cin >> num; // 读取输入的数字
originalNum = num; // 保存原始数字,因为num会在后续操作中被修改
// 计算位数
int count = 0; // 初始化计数器
int temp = num; // 临时变量,用于计算位数
while (temp > 0) { // 当temp大于0时继续循环
temp /= 10; // 每次除以10
count++; // 位数加1
}
// 输出位数
cout << count << endl; // 输出计算得到的位数
// 输出每一位数字
int divisor = pow(10, count - 1); // 计算最高位的除数
while (divisor > 0) { // 当除数大于0时继续循环
cout << num / divisor; // 输出当前位的数字
if (divisor > 1) cout << " "; // 如果不是最后一位,输出空格
num %= divisor; // 更新num为余数
divisor /= 10; // 除数除以10,准备处理下一位
}
cout << endl; // 输出换行
// 按逆序输出
while (originalNum > 0) { // 当原始数字大于0时继续循环
cout << originalNum % 10; // 输出最后一位
originalNum /= 10; // 去掉最后一位
}
cout << endl; // 输出换行
return 0; // 程序结束
}
代码解析
- 代码中每一行都添加了注释,解释了该行的作用。
- 这种实现方法不使用数组,而是通过数学运算来处理每一位数字。
- 时间复杂度是O(log n),其中n是输入的数字,因为我们需要处理每一位数字。
- 空间复杂度是O(1),因为只使用了常数级的额外空间。
- 这个解决方案适用于不超过5位的正整数,完全符合题目要求。
1121. "倒"数
问题描述
输入一个正整数N(0<N<2147483647),将这个数倒着合成一个新数后输出。注意:不保留前导零。
解题思路
- 读取输入:读取给定的正整数N。
- 逐位处理:从个位开始,逐位提取数字。
- 构建新数:将提取的数字按相反顺序构建成新的数。
- 输出结果:输出构建的新数。
代码实现
cpp
#include <iostream>
using namespace std;
int main() {
int N; // 声明变量存储输入的正整数
cin >> N; // 读取输入的数字
int reversedNum = 0; // 用于存储倒序后的新数
while (N > 0) { // 当N大于0时继续循环
int digit = N % 10; // 获取N的最后一位数字
reversedNum = reversedNum * 10 + digit; // 将digit添加到reversedNum的末尾
N /= 10; // 去掉N的最后一位
}
cout << reversedNum << endl; // 输出倒序后的新数
return 0; // 程序结束
}
代码解析
-
int N;
:声明变量N来存储输入的正整数。 -
cin >> N;
:从标准输入读取正整数N。 -
int reversedNum = 0;
:初始化reversedNum为0,用于存储倒序后的新数。 -
while (N > 0)
:当N大于0时,继续循环处理每一位数字。 -
int digit = N % 10;
:通过取模运算获取N的最后一位数字。 -
reversedNum = reversedNum * 10 + digit;
:将新的数字添加到reversedNum的末尾。 -
N /= 10;
:去掉N的最后一位数字。 -
cout << reversedNum << endl;
:输出倒序后的新数。 -
这种方法的时间复杂度是O(log N),其中N是输入的数字,因为我们需要处理每一位数字。
-
空间复杂度是O(1),因为我们只使用了常数级的额外空间。
-
这个解决方案自动处理了前导零的问题,因为在构建新数时,前导零自然被忽略了。
-
该实现方法适用于题目给定范围内的所有正整数(0<N<2147483647)。
1469. 数的统计
问题描述
计算在区间1到n的所有整数中,数字x(0≤x≤9)共出现了多少次。
解题思路
- 读取输入:读取n和x的值。
- 遍历区间:从1遍历到n。
- 统计出现次数 :
- 对每个数,分解其各个位。
- 检查每一位是否等于x。
- 如果等于,计数器加1。
- 输出结果:输出最终的计数。
代码实现
cpp
#include <iostream>
using namespace std;
int main() {
int n, x; // 声明变量n和x
cin >> n >> x; // 读取输入的n和x
int count = 0; // 初始化计数器
// 遍历从1到n的每个数
for (int i = 1; i <= n; i++) {
int current = i; // 当前处理的数
// 分解current的每一位并检查
while (current > 0) {
if (current % 10 == x) { // 如果当前位等于x
count++; // 计数器加1
}
current /= 10; // 去掉最后一位
}
}
cout << count << endl; // 输出x出现的次数
return 0; // 程序结束
}
代码解析
-
int n, x;
:声明变量n和x,分别表示区间上限和要统计的数字。 -
cin >> n >> x;
:从标准输入读取n和x的值。 -
int count = 0;
:初始化计数器count为0。 -
for (int i = 1; i <= n; i++)
:遍历从1到n的每个数。 -
int current = i;
:将当前处理的数赋值给current。 -
while (current > 0)
:循环处理current的每一位。 -
if (current % 10 == x)
:检查current的最后一位是否等于x。 -
count++;
:如果等于x,计数器加1。 -
current /= 10;
:去掉current的最后一位。 -
cout << count << endl;
:输出最终的计数结果。 -
时间复杂度:O(n log n),其中n是输入的上限值。对每个数都需要检查其每一位。
-
空间复杂度:O(1),只使用了常数级的额外空间。
-
这个解决方案适用于题目给定的所有输入范围(n是int范围内的整数)。
-
该方法通过逐个检查每个数的每一位来统计x的出现次数,确保了准确性。
1511. 数字之和为13的整数
问题描述
求出1到n范围内的整数中,数字之和为13的数的个数。n不超过10000000。
解题思路
- 遍历范围:从1遍历到n。
- 计算数字和:对每个数,计算其各位数字之和。
- 统计符合条件的数:如果数字和等于13,计数器加1。
- 输出结果:输出最终的计数。
代码实现
cpp
#include <iostream>
using namespace std;
int main() {
int n; // 声明变量n
cin >> n; // 读取输入的n
int count = 0; // 初始化计数器
// 遍历从1到n的每个数
for (int i = 1; i <= n; i++) {
int sum = 0; // 用于存储当前数字的各位之和
int current = i; // 当前处理的数
// 计算current的各位数字之和
while (current > 0) {
sum += current % 10; // 加上最后一位
current /= 10; // 去掉最后一位
}
// 如果和为13,计数器加1
if (sum == 13) {
count++;
}
}
cout << count << endl; // 输出符合条件的数的个数
return 0; // 程序结束
}
代码解析
-
int n;
:声明变量n,用于存储输入的范围上限。 -
cin >> n;
:从标准输入读取n的值。 -
int count = 0;
:初始化计数器count为0。 -
for (int i = 1; i <= n; i++)
:遍历从1到n的每个数。 -
int sum = 0;
:初始化sum为0,用于存储当前数字的各位之和。 -
int current = i;
:将当前处理的数赋值给current。 -
while (current > 0)
:循环处理current的每一位。 -
sum += current % 10;
:将current的最后一位加到sum上。 -
current /= 10;
:去掉current的最后一位。 -
if (sum == 13)
:检查sum是否等于13。 -
count++;
:如果sum等于13,计数器加1。 -
cout << count << endl;
:输出最终的计数结果。 -
时间复杂度:O(n log n),其中n是输入的上限值。对每个数都需要计算其各位之和。
-
空间复杂度:O(1),只使用了常数级的额外空间。
-
这个解决方案适用于题目给定的所有输入范围(n≤10000000)。
-
该方法通过逐个检查每个数的各位之和来统计符合条件的数的个数,确保了准确性。
-
对于较大的n值,这种方法可能会比较耗时,但在给定的范围内仍然是可行的。
1149. 回文数个数
问题描述
给定一个正整数n(1≤n≤10000),求出1到n之间(包括1和n)的回文数的个数。
解题思路
- 遍历范围:从1遍历到n。
- 判断回文:对每个数,判断是否为回文数。
- 统计回文数:如果是回文数,计数器加1。
- 输出结果:输出最终的计数。
代码实现
cpp
#include <iostream>
using namespace std;
int main() {
int n; // 声明变量n
cin >> n; // 读取输入的n
int count = 0; // 初始化计数器
// 遍历从1到n的每个数
for (int i = 1; i <= n; i++) {
int original = i; // 保存原始数字
int reversed = 0; // 用于存储反转后的数字
int temp = i; // 临时变量,用于反转过程
// 反转数字
while (temp > 0) {
reversed = reversed * 10 + temp % 10;
temp /= 10;
}
// 判断是否为回文数
if (original == reversed) {
count++;
}
}
cout << count << endl; // 输出回文数的个数
return 0; // 程序结束
}
代码解析
-
int n;
:声明变量n,用于存储输入的范围上限。 -
cin >> n;
:从标准输入读取n的值。 -
int count = 0;
:初始化计数器count为0。 -
for (int i = 1; i <= n; i++)
:遍历从1到n的每个数。 -
int original = i;
:保存原始数字。 -
int reversed = 0;
:用于存储反转后的数字。 -
int temp = i;
:临时变量,用于反转过程。 -
while (temp > 0)
:循环反转数字。 -
reversed = reversed * 10 + temp % 10;
:构建反转后的数字。 -
temp /= 10;
:去掉temp的最后一位。 -
if (original == reversed)
:判断原数字是否等于反转后的数字。 -
count++;
:如果是回文数,计数器加1。 -
cout << count << endl;
:输出最终的计数结果。 -
时间复杂度:O(n log n),其中n是输入的上限值。对每个数都需要进行反转操作。
-
空间复杂度:O(1),只使用了常数级的额外空间。
-
这个解决方案适用于题目给定的所有输入范围(1≤n≤10000)。
-
该方法通过反转每个数并与原数比较来判断是否为回文数,确保了准确性。
-
对于给定的范围(最大10000),这种方法是高效且可行的。
1846. 阿尔法乘积
问题描述
计算一个整数的阿尔法乘积。阿尔法乘积的计算规则是:
- 如果是个位数,阿尔法乘积就是它本身。
- 否则,计算各位非0数字的乘积,然后重复此过程直到得到一个个位数。
解题思路
- 循环计算:使用循环代替递归,重复计算直到结果为个位数。
- 乘积计算:在每次循环中计算各位非0数字的乘积。
- 结果判断:当结果小于10时结束循环。
代码实现
cpp
#include <iostream>
using namespace std;
int main() {
int n; // 声明变量n
cin >> n; // 读取输入的整数
while (n >= 10) { // 当n不是个位数时继续循环
int product = 1; // 用于存储各位非0数字的乘积
int temp = n; // 临时变量,用于分解数字
// 计算各位非0数字的乘积
while (temp > 0) {
int digit = temp % 10; // 获取最后一位数字
if (digit != 0) {
product *= digit; // 如果不是0,则乘到product中
}
temp /= 10; // 去掉最后一位
}
n = product; // 更新n为新的乘积
}
cout << n << endl; // 输出最终结果
return 0; // 程序结束
}
代码解析
-
int n;
:声明变量n,用于存储输入的整数和中间结果。 -
cin >> n;
:从标准输入读取n的值。 -
while (n >= 10)
:外层循环,当n不是个位数时继续计算。 -
int product = 1;
:初始化product为1,用于存储各位非0数字的乘积。 -
int temp = n;
:临时变量temp,用于分解数字。 -
while (temp > 0)
:内层循环,处理temp的每一位数字。 -
int digit = temp % 10;
:获取temp的最后一位数字。 -
if (digit != 0) { product *= digit; }
:如果digit不为0,则乘到product中。 -
temp /= 10;
:去掉temp的最后一位。 -
n = product;
:更新n为新的乘积。 -
cout << n << endl;
:输出最终结果。 -
时间复杂度:O(log n * log n),其中n是输入的整数。外层循环最多执行log n次,每次内层循环也最多执行log n次。
-
空间复杂度:O(1),只使用了常数级的额外空间。
-
这个解决方案适用于题目给定的所有输入范围(int范围内的正整数)。
-
该方法通过循环实现了阿尔法乘积的计算,避免了使用递归和函数调用,符合题目要求。