codechef:smallfactorial中的错误答案错误

#include int fact(int k) { int j,f=1; for(j=1;j<=k;j++) f*=j; return f; } int main() { int t,i,n[100],s[100],j; scanf("%d",&t); for(i=0;i<t;i++) { scanf("%d",&n[i]); } for(j=0;j<t;j++) { s[j]=fact(n[j]); printf("%d \n",s[j]); } return 0; } 

系统会要求您计算一些小正整数的阶乘。 输入

整数t,1 <= t <= 100,表示测试用例的数量,后跟t行,每行包含一个整数n,1 <= n <= 100。 产量

对于输入处给出的每个整数n,显示一个值为n的行! 例

样品输入:4 1 2 5 3样品输出:1 2 120 6

您的代码将为给定的测试用例提供正确的结果,但这并不能certificate您的代码有效。 这是错误的,因为整数溢出。 试着计算100! 通过您的程序,您将看到问题所在。


我的回答缺乏细节。 我将更新此内容以添加现在问题答案的详细信息。

C对可存储在变量中的最大和最小大小有限制。 对于进行任意精度算术,通常建议使用bignum库,如PHIFounder所建议的那样。

但是,在目前的情况下,不可能使用外部库。 在这种情况下,数组可用于存储超过可能的整数最大值的整数。 OP已经发现了这种可能性并使用了它。 但是,她的实现可以使用许多优化。

最初可以减少使用像这样的大型数组。 可以使用单个变量来存储测试用例,而不是使用100个变量的数组。 在测试用例中使用大型数组和读取只有在使用缓冲区从stdinstdin才能进行优化,否则通过在for循环中添加scanf来调用scanf来读取测试用例不会更好个别测试案例。

您可以选择使用缓冲来提高速度,也可以使用单个整数而不是100个整数的数组。 在这两种情况下,OP上与codechef链接的当前解决方案都会有所改进。 对于缓冲,您可以参考这个问题 。 如果您在codechef上看到时序结果,则缓冲的结果可能不可见,因为其余逻辑中的操作数很多。

现在关于使用array[200]第二件事。 关于codechef的博客教程使用200个元素的数组来演示逻辑。 教程本身指出,这是一种天真的方法。 在每个arrays位置存储一个数字是一个巨大的内存浪费。 这种方法还会导致更多的操作导致更慢的解决方案。 一个整数至少可以存储5位数(-32768到32767)并且通常可以存储更多数字。 您可以将中间结果存储在用作templong long int ,并使用全部5位数。 简化本身将导致仅使用arr[40]而不是arr[200] 。 代码需要一些额外的更改来处理前向传输,并且会变得有点复杂,但速度和内存的改进都是可见的。

您可以参考此信息来查看我的解决方案,或者您可以看到此特定解决方案 。 我只能使用26元素,有可能进一步降低。

我建议您在codereview上提交代码,以便审核您的代码。 还有很多问题最好在那里进行审查。

这里,你的数组索引应该从0开始而不是1,我的意思是ji应该在for循环中初始化为0。

此外,尝试使用调试器,这将有助于您找到错误。

如果我的猜测是正确的你使用turbo C,如果是,那么我的建议是你开始使用MinGW或Cygwin并尝试在CLI上编译,无论如何只是一个推荐。

可能还有一个问题可能是,为什么codechef不接受你已定义函数接受整数的代码,然后你传递数组,可能这段代码对你有用:

 #include int fact(int a[],int n)// here in function prototype I have defined it to take array as argument where n is array size. { int j=0,f=1,k; for (k=a[j];k>0;k--) f*=k; return f; } int main() { int t,i,n[100],s[100],j; setbuf(stdout,NULL); printf("enter the test cases\n"); scanf("%d",&t); //given t test cases for(i=0;i 

注意: - 在OP的最后一次编辑之后,这个实现有一些限制,它不能计算较大数字的阶乘,比如100 ,再次编辑已经在不同的轨道上提出问题,这个答案仅适用于小因子

上面的程序只适用于小数字,这意味着最多7个!之后,该代码没有给出正确的结果,因为8! 值为40320在c语言中,SIGNED INTEGER范围为-32768到+32767,但> 8个阶乘值超出该值,因此整数不能存储这些值,因此上面的代码无法给出正确的值,我们声明s [100 ]作为LONG INT,但它也适用于某些范围