【发布时间】:2022-01-11 20:54:06
【问题描述】:
我想用 C++ 解决这个图片中所示的问题
将 f(n) 定义为 n 位的阶乘之和。例如,f(342) = 3! + 4! + 2! = 32。
将 sf(n) 定义为 f(n) 的位数之和。所以 sf(342) = 3 + 2 = 5。
将 g(i) 定义为满足 sf(n) = i 的最小正整数 n。虽然sf(342)是5,但是sf(25)也是5,可以验证g(5)是25。
将 sg(i) 定义为 g(i) 的位数之和。所以 sg(5) = 2 + 5 = 7。
进一步,可以验证 g(20) 为 267 且 ∑ sg(i) for 1 ≤ i ≤ 20 为 156。
对于 1 ≤ i ≤ 150,∑ sg(i) 是什么?
图片:
这是我的方法。我的代码需要很长时间才能运行,并且可以正常工作
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int factorial(int n);
std::vector<int> int_to_vector(int n);
int sum_vector(std::vector<int> v);
int get_smallest_number(std::vector<int> v, int sum, int n);
int sum_sg(int n )
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int q;
int m,n;
int g;
int sum = 0;
std::vector<int> vec;
cin>>q;
if( 1<=q && q<=100000){
std::vector<int> s;
int fact = 0;
int sg = 0;
for ( int i = 0; i < q; i++){
cin>>n>>m;
fact = factorial(n);
s = int_to_vector(fact);
sum = sum_vector(s);
g = get_smallest_number(s, sum, n);
s = int_to_vector(g);
sum = sum_vector(s);
}
}
return 0;
}
int factorial(int n){
if (n==0) return 1;
return factorial(n-1)*n;
}
std::vector<int> int_to_vector(int n){
std::vector<int> numbers;
while(n>0)
{
numbers.push_back(n%10);
n/=10;
}
return numbers;
}
int sum_vector(std::vector<int> v){
int sum=0;
for(int i = 0; i < v.size(); i++){
sum+=v.at(i);
}
return sum;
}
int get_smallest_number(std::vector<int> v, int sum, int n){
int i = 0;
int factoriel = 1;
std::vector<int> vect;
int sum2 = 0;
while( i < n){
factoriel = factorial(i);
vect = int_to_vector(factoriel);
sum2 = sum_vector(vect);
if( sum2 == sum) return i;
i++ ;
}
return n;
}
我认为是递归解决方案,但实现起来似乎更复杂。有没有使用现代 C++ 和 STL 的解决方案?
【问题讨论】:
-
当你可以传递(const)引用时,不要按值传递向量
-
我在计算“数字阶乘之和”的代码中什么也看不到。所以这就是你需要开始的地方。编写一个可以计算
f(342)并返回值32的函数。 -
使用递归函数计算阶乘很慢。一个简单的循环会更快。而且由于您只需要个位数的阶乘,因此查找表会更快,例如
int factorials[10] = {1,1,2,6,24,120,... -
user3386109,如果你在代码中看起来不错,我会尝试计算阶乘事实,我将结果转换为向量
,其中它的值是事实的数字,然后我总结向量的所有值,以便我得到 sf(n) (阶乘 (n) 的数字总和)