我试图解决来自www.spoj.com的这个练习:FCTRL - 阶乘
如果你好奇的话,你不需要真正阅读它,只需完成它 :)
首先,我用C++实现了它(这是我的解决方案):
#include <iostream>
using namespace std;
int main() {
unsigned int num_of_inputs;
unsigned int fact_num;
unsigned int num_of_trailing_zeros;
std::ios_base::sync_with_stdio(false); // turn off synchronization with the C library’s stdio buffers (from https://dev59.com/eH3aa4cB1Zd3GeqPbEuh#22225421)
cin >> num_of_inputs;
while (num_of_inputs--)
{
cin >> fact_num;
num_of_trailing_zeros = 0;
for (unsigned int fives = 5; fives <= fact_num; fives *= 5)
num_of_trailing_zeros += fact_num/fives;
cout << num_of_trailing_zeros << "\n";
}
return 0;
}
我将其上传作为解决方案,适用于g++ 5.1
但是后来我看到一些评论声称他们的执行时间少于0.1。由于我无法想出更快的算法,我尝试在C中实现相同的代码:
#include <stdio.h>
int main() {
unsigned int num_of_inputs;
unsigned int fact_num;
unsigned int num_of_trailing_zeros;
scanf("%d", &num_of_inputs);
while (num_of_inputs--)
{
scanf("%d", &fact_num);
num_of_trailing_zeros = 0;
for (unsigned int fives = 5; fives <= fact_num; fives *= 5)
num_of_trailing_zeros += fact_num/fives;
printf("%d", num_of_trailing_zeros);
printf("%s","\n");
}
return 0;
}
我将其上传为解决方案,适用于gcc 5.1
现在代码几乎相同,我按照这里建议的方式添加了std::ios_base::sync_with_stdio(false);
到C ++代码中,以关闭与C库的stdio缓冲区的同步。 我还将printf(“%d \ n”,num_of_trailing_zeros);
分成, printf(“%d”,num_of_trailing_zeros); printf(“%s”,“\n”);
来补偿cout << num_of_trailing_zeros<< "\n";
中对operator<<
的双重调用。
但是我仍然看到C与C ++代码相比具有x9更好的性能和更低的内存使用率。
为什么会这样呢?
编辑
我在C代码中将unsigned long
修正为unsigned int
。它应该是unsigned int
,上面显示的结果与新版本(unsigned int
)相关。
std::ostringstream
来累积输出并在结尾时一次性将其发送到std::cout
可以将时间缩短到0.02。在循环中使用std::cout
会在他们的环境中变慢,我认为没有简单的方法可以改善它。 - Blastfurnace