题目## 题目
解题思路
-
完全数的定义:一个数等于它的所有真因子(除了自身以外的约数)之和
- 例如:28的真因子有1,2,4,7,14,且1+2+4+7+14=28
-
实现思路:
- 遍历1到 n n n 的每个数
- 对每个数找出其所有真因子
- 判断真因子之和是否等于该数本身
- 统计满足条件的数的个数
-
优化:
- 只需要遍历到 n \sqrt{n} n 就可以找到所有因子
- 已知的完全数很少,可以直接判断
代码
#include <iostream>
using namespace std;
bool isPerfectNumber(int num) {
if (num <= 1) return false;
int sum = 1; // 1总是因子
// 只需要遍历到sqrt(num)
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) {
sum += i;
if (i * i != num) { // 避免平方数重复计算
sum += num / i;
}
}
}
return sum == num;
}
int main() {
int n;
while (cin >> n) {
int count = 0;
for (int i = 1; i <= n; i++) {
if (isPerfectNumber(i)) {
count++;
}
}
cout << count << endl;
}
return 0;
}
import java.util.Scanner;
public class Main {
private static boolean isPerfectNumber(int num) {
if (num <= 1) return false;
int sum = 1; // 1总是因子
// 只需要遍历到sqrt(num)
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) {
sum += i;
if (i * i != num) { // 避免平方数重复计算
sum += num / i;
}
}
}
return sum == num;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int n = sc.nextInt();
int count = 0;
for (int i = 1; i <= n; i++) {
if (isPerfectNumber(i)) {
count++;
}
}
System.out.println(count);
}
}
}
def is_perfect_number(num):
if num <= 1:
return False
sum_factors = 1 # 1总是因子
# 只需要遍历到sqrt(num)
i = 2
while i * i <= num:
if num % i == 0:
sum_factors += i
if i * i != num: # 避免平方数重复计算
sum_factors += num // i
i += 1
return sum_factors == num
while True:
try:
n = int(input())
count = 0
for i in range(1, n + 1):
if is_perfect_number(i):
count += 1
print(count)
except EOFError:
break
算法及复杂度
- 算法:试除法找因子
- 时间复杂度: O ( n n ) \mathcal{O}(n\sqrt{n}) O(nn) - 需要遍历1到n的每个数,每个数需要 O ( n ) \mathcal{O}(\sqrt{n}) O(n)的时间找因子
- 空间复杂度: O ( 1 ) \mathcal{O}(1) O(1) - 只使用了常数额外空间
解题思路
这是一个简单的字符串逆序问题,需要将输入的字符串反转后输出。需要注意的是输入的字符串可能包含空格。
关键点
-
数据范围:
- 字符串长度: 1 ≤ l e n ( s t r ) ≤ 10000 1 \leq len(str) \leq 10000 1≤len(str)≤10000
- 字符串可以包含空格
-
处理要求:
- 保持原有的空格
- 完整反转整个字符串
代码
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string str;
// 使用getline读取整行,包括空格
getline(cin, str);
// 直接反转字符串
reverse(str.begin(), str.end());
cout << str << endl;
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 使用nextLine()读取整行,包括空格
String str = sc.nextLine();
// 使用StringBuilder反转字符串
StringBuilder sb = new StringBuilder(str);
System.out.println(sb.reverse().toString());
}
}
while True:
try:
# 读取整行,包括空格
s = input()
# 使用切片反转字符串
print(s[::-1])
except:
break
算法及复杂度
算法分析
-
输入处理:
- 使用能读取整行的方法(包括空格)
- C++使用
getline - Java使用
nextLine() - Python使用
input()
-
反转方法:
- C++使用
algorithm库的reverse函数 - Java使用
StringBuilder的reverse方法 - Python使用切片
[::-1]
- C++使用
复杂度分析
- 时间复杂度: O ( n ) \mathcal{O}(n) O(n) - 其中 n n n 是字符串长度,需要遍历一次字符串
- 空间复杂度: O ( 1 ) \mathcal{O}(1) O(1) - 原地反转不需要额外空间(某些语言实现可能需要 O ( n ) \mathcal{O}(n) O(n) 的空间)
19万+

被折叠的 条评论
为什么被折叠?



