题目## 题目
HJ76 尼科彻斯定理
解题思路
- 尼科彻斯定理说明任何整数的立方都可以写成连续奇数的和
- 对于数字 n n n,需要找到 n n n 个连续奇数,使其和等于 n n n 的立方
- 分析规律可以发现:
- 对于 n = 1 n=1 n=1: 1 3 = 1 1^3=1 13=1
- 对于 n = 2 n=2 n=2: 2 3 = 3 + 5 2^3=3+5 23=3+5
- 对于 n = 3 n=3 n=3: 3 3 = 7 + 9 + 11 3^3=7+9+11 33=7+9+11
- 对于 n = 4 n=4 n=4: 4 3 = 13 + 15 + 17 + 19 4^3=13+15+17+19 43=13+15+17+19
- 可以发现第一个奇数是 n 2 − n + 1 n^2-n+1 n2−n+1
- 后续的数字每次加2直到加够 n n n 个数
代码
#include <iostream>
#include <string>
using namespace std;
string solution(int m) {
// 计算第一个奇数
int first = m * m - m + 1;
string result = "";
// 生成m个连续奇数
for(int i = 0; i < m; i++) {
if(i > 0) {
result += "+";
}
result += to_string(first + 2 * i);
}
return result;
}
int main() {
int m;
cin >> m;
cout << solution(m) << endl;
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
System.out.println(solution(m));
}
public static String solution(int m) {
// 计算第一个奇数
int first = m * m - m + 1;
StringBuilder sb = new StringBuilder();
// 生成m个连续奇数
for(int i = 0; i < m; i++) {
if(i > 0) {
sb.append("+");
}
sb.append(first + 2 * i);
}
return sb.toString();
}
}
def solution(m):
# 计算第一个奇数
first = m * m - m + 1
result = []
# 生成m个连续奇数
for i in range(m):
result.append(str(first + 2 * i))
# 用+连接所有数字
return '+'.join(result)
# 处理输入
m = int(input())
print(solution(m))
算法及复杂度
- 算法:数学规律 + 字符串拼接
- 时间复杂度: O ( m ) \mathcal{O}(m) O(m) - 需要生成 m m m 个数字并拼接
- 空间复杂度: O ( 1 ) \mathcal{O}(1) O(1) - 只需要常数级额外空间
解题思路
这是一个将真分数分解为埃及分数(分子为1的分数)的问题。需要使用贪心算法来解决:
-
解析输入:
- 将输入的字符串解析为分子和分母
- 确保输入是一个真分数(分子小于分母)
-
贪心算法实现:
- 对于分数 a/b,找到不大于 a/b 的最大埃及分数 1/n
- 使用辗转相除法化简分数
- 递归处理剩余的分数部分
-
注意事项:
- 需要处理分子和分母的最大公约数
- 确保每一步的分解都是有效的
- 处理特殊情况(如分子为1的情况)
代码
#include <iostream>
#include <string>
using namespace std;
using ll = long long;
ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a % b);
}
void egyptianFraction(ll nr, ll dr) {
// 如果分子为0或分母为0,返回
if (nr == 0 || dr == 0)
return;
// 如果分子能整除分母
if (dr % nr == 0) {
cout << "1/" << dr/nr;
return;
}
// 如果分母能整除分子
if (nr % dr == 0) {
cout << nr/dr;
return;
}
// 如果分子大于分母
if (nr > dr) {
cout << nr/dr << "+";
egyptianFraction(nr%dr, dr);
return;
}
// 找到第一个大于dr/nr的分母
ll n = dr/nr + 1;
cout << "1/" << n;
// 计算新的分子和分母
ll new_nr = nr * n - dr;
ll new_dr = dr * n;
// 化简分数
ll g = gcd(abs(new_nr), new_dr);
new_nr /= g;
new_dr /= g;
if (new_nr != 0) {
cout << "+";
egyptianFraction(new_nr, new_dr);
}
}
int main() {
string input;
cin >> input;
ll pos = input.find('/');
ll nr = stoll(input.substr(0, pos));
ll dr = stoll(input.substr(pos + 1));
// 化简输入的分数
ll g = gcd(nr, dr);
nr /= g;
dr /= g;
egyptianFraction(nr, dr);
cout << endl;
return 0;
}
import java.util.*;
public class Main {
public static long gcd(long a, long b) {
return b == 0 ? a : gcd(b, a % b);
}
public static void egyptianFraction(long nr, long dr) {
if (nr == 0 || dr == 0)
return;
if (dr % nr == 0) {
System.out.print("1/" + dr/nr);
return;
}
if (nr % dr == 0) {
System.out.print(nr/dr);
return;
}
if (nr > dr) {
System.out.print(nr/dr + "+");
egyptianFraction(nr%dr, dr);
return;
}
long n = dr/nr + 1;
System.out.print("1/" + n);
long new_nr = nr * n - dr;
long new_dr = dr * n;
long g = gcd(Math.abs(new_nr), new_dr);
new_nr /= g;
new_dr /= g;
if (new_nr != 0) {
System.out.print("+");
egyptianFraction(new_nr, new_dr);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
String[] parts = input.split("/");
long nr = Integer.parseInt(parts[0]);
long dr = Integer.parseInt(parts[1]);
long g = gcd(nr, dr);
nr /= g;
dr /= g;
egyptianFraction(nr, dr);
System.out.println();
}
}
import math
def egyptian_fraction(nr, dr):
if nr == 0 or dr == 0:
return
if dr % nr == 0:
print(f"1/{dr//nr}", end="")
return
n = math.ceil(dr/nr)
print(f"1/{n}", end="")
new_nr = nr * n - dr
new_dr = dr * n
if new_nr != 0:
print("+", end="")
egyptian_fraction(new_nr, new_dr)
# 读取输入
fraction = input().strip()
nr, dr = map(int, fraction.split('/'))
# 计算并输出结果
egyptian_fraction(nr, dr)
print() # 换行
算法及复杂度
- 算法:贪心算法 + 辗转相除法
- 时间复杂度: O ( log n ) \mathcal{O}(\log n) O(logn) - 每次迭代分母会显著增大
- 空间复杂度: O ( log n ) \mathcal{O}(\log n) O(logn) - 递归调用栈的深度
353

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



