我正在尝试编写一个代码,用于计算特定数字(大数)的阶乘中的尾随零的数量。但是,对于较小的数字,我得到了正确的结果,但是对于较大的数字,偏差不断增加。我的逻辑有什么问题
#include <stdio.h>
int main(void) {
int t;
scanf("%d", &t);
while (t > 0) {
int factorten = 0, factorfive = 0, factortwo = 0, remainingfive = 0,
remainingtwo = 0;
unsigned int factors = 0;
unsigned int n;
scanf("%u", &n);
for (unsigned int i = n; i > 0; i--) {
if (i % 10 == 0) {
factorten++;
continue;
} else if (i % 5 == 0) {
factorfive++;
continue;
} else if (i % 2 == 0) {
// int new = i;
// while(new % 2 == 0)
//{
// new = new / 2;
factortwo++;
//}
continue;
}
}
factors = factors + factorten;
printf("%u\n", factors);
if (factorfive % 2 == 0 && factorfive != 0) {
factors = factors + (factorfive / 2);
} else {
remainingfive = factorfive % 2;
factors = factors + ((factorfive - remainingfive) / 2);
}
printf("%u\n", factors);
if (factortwo % 5 == 0 && factortwo != 0) {
factors = factors + (factortwo / 5);
} else {
remainingtwo = factortwo % 5;
factors = factors + ((factortwo - remainingtwo) / 5);
}
printf("%u\n", factors);
if ((remainingfive * remainingtwo % 10) == 0 &&
(remainingfive * remainingtwo % 10) != 0) {
factors++;
}
printf("%u\n", factors);
t--;
}
}
示例输入:
6
3
60
100
1024
23456
8735373
示例输出:
0
14
24
253
5861
2183837
我的输出
0
13
23
235
5394
2009134
答案 0 :(得分:3)
编辑:忽略前两个,它们不是最理想的。第三种算法是最优的。
我认为这可以做你想做的事情,但是更简单并且有效:
int tzif(int n)
{
int f2 = 0, f5 = 0;
for (;n > 1; n--)
{
int x = n;
for (;x % 2 == 0; x /= 2)
f2++;
for (;x % 5 == 0; x /= 5)
f5++;
}
return f2 > f5 ? f5 : f2;
}
它计算数字N ... 2的2因子和5因子。然后它返回两者中较小的一个(因为在不添加5个因子的情况下添加2个因子是无用的,反之亦然)。你的代码太奇怪了我无法分析。
我认为这也应该有效,因为一个因子将有足够的2因子来“覆盖”5个因素:
int tzif(int n)
{
int f5 = 0;
for (;n > 1; n--)
for (x = n;x % 5 == 0; x /= 5)
f5++;
return f5;
}
这只计算5个因子并返回。
我认为另一种方法应该有效:
int tzif(int n)
{
int f5 = 0;
for (int d = 5; d <= n; d *= 5)
f5 += n / d;
return f5;
}
计算每五个数字(每个数字有5个因子),然后每个第25个数字(每个都有另一个5个因子),等等。
答案 1 :(得分:0)
有3个柜台--c2,c5,c10。
我认为检查应该是
最后0的数字将是
smaller_of(c2,c5)+ c10
尝试使用此代码。应该工作。
答案 2 :(得分:0)
首先,trailing 0
中的N!
由因子2 and 5
(10
)确定。在这种情况下factors 2
factors 5
总是更需要计算factors 5
中N!
的{{1}}。{/ 1}}。
(N!/5)
会在N!
中为您提供 5(5 ^ 1)的倍数
(N!/25)
会在N!
中为您提供 25(5 ^ 2)的倍数
(N!/125)
会在N!
中为您提供 125(5 ^ 3)的倍数
...
(N!/5^n)
会在N!
当您添加multiple of 5
时,您添加25, 125, ..., 5^n
的倍数,当您添加multiple of 25
时,您也会添加125, ..., 5^n
的倍数等...
在这种情况下,您只需要迭代power of 5
小于或等于N
并添加该5次方的倍数。
代码:
long long trailing_zeros(long long N) {
long long zeros = 0;
for (long long power5 = 5; power5 <= N; power5 *= 5)
zeros += N / power5;
return zeros;
}
答案 3 :(得分:0)
#include<iostream>
int main()
{
int size,i;
std::cin >> size;
int*fact;
fact = new int[size];
for (i = 0; i < size; i++)
{
std::cin >> fact[size];
}
for (i = 0; i < size; i++)
{
int con = 5;
int multiple = 0;
do
{
multiple = multiple+(fact[size] / con);
con = con * 5;
} while (con < fact[size]);
std::cout << multiple <<'\n';
}
return 0;
}
此代码适用于单个输入..对于多个输入,它打印最后输入的数字的o / p ...出了什么问题......我不能想到它