0
#include<stdio.h>
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

4

3 回答 3

1

您的代码将为给定的测试用例提供正确的结果,但这并不能证明您的代码有效。这是错误的,因为整数溢出。尝试100!通过您的程序进行计算,您会发现问题所在。


我的回答缺乏细节。我将对此进行更新,以添加详细信息以回答目前的问题。

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

然而,在当前情况下,无法使用外部库。在这种情况下,数组可用于存储超出可能整数最大值的整数。OP 已经发现了这种可能性并使用了它。然而,她的实现可以使用许多优化。

最初可以减少使用这样的大型阵列。可以使用单个变量来存储测试用例,而不是使用 100 个变量的数组。仅当您使用缓冲区读取时,在测试用例中使用大数组和读取才能进行优化,stdin否则它不会比通过在循环中scanf添加 a 来遍历单个测试用例来调用读取测试用例更好.scanffor

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

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

你可以参考这个来查看我的解决方案,或者你可以查看这个特定的解决方案。我只能将使用降低到26元素,并且有可能将其进一步降低。

我建议您将代码放在codereview上,以便审查您的代码。还有更多问题最好在那里进行审查。

于 2013-07-12T17:51:27.717 回答
0

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

此外,尝试使用调试器,这将帮助您发现错误。

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

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

#include<stdio.h>
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<t;i++)
    {
      scanf("%d",&n[i]); //value of the test cases whose factorial is to be calculated
    }
  for(j=0;j<t;j++)
    {
      s[j]=fact(&n[j],t);// and here I have passed it as required 

      printf("\n %d",s[j]); //output
     }
  return 0;
}

注意:-在 OP 的最后一次编辑之后,此实现有一些限制,它无法计算较大数字的阶乘,例如100,再次编辑将问题放在不同的轨道上,此答案仅适用于小阶乘

于 2013-07-12T14:26:14.017 回答
0

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

于 2013-09-20T08:40:52.297 回答