c ++在阶乘中的大数

时间:2016-11-19 17:29:20

标签: c++

我正在尝试制作一个问题的程序“给定一个正整数 a ,最小正整数 g 是什么,以便 g! a!的平方的倍数?

示例输入

1(测试用例)

4

示例输出

8

说明:8!= 40320可被4整除!^ 2 = 24 ^ 2 = 576。此外,它是最小的一个,因为7!= 5040不能被576整除。

程序成功,但是当输入大于20时我遇到了麻烦。它不会输出任何内容。

有什么建议吗?

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;


int main() {
long long a,b,c=1,d,e=1,f=1,g=0,k;
cin>>a;
while(a>0){
    cin>>b;
    g=0;
    e=1;
    c=1;
    f=1;
    for (long long i=1; i<=b; i++){
        c=c*i;
    }
    d=c*c;
    for(long long j=1; e!=0; j++){
        f=f*j;
        g=g+2;
        e=f%d;
        if(c==e)
        cout<<g<<endl;
    }
    a--;
}
return 0;

}

3 个答案:

答案 0 :(得分:0)

对于值大于20的所有输入,暴力会导致整数溢出。我得到了一个更好的解决方案,其时间复杂度为O(T) T = number of test cases,并使用常量空间。

解决方案:对于所有g的值等于2*a

         (a!)^2 = (a!)*a*(a-1)*(a-2)*..3*2*1

我们的目标是以(a!)*a*(a-1)*(a-2)*..3*2*1的形式将g!乘以所需的最小可能整数。

如果我们将2a,a-1,a-2,...,3,2,1中的每一个相乘,那么我们就会得到

        (a!)*2a*(2a-2)*(2a-4)*..6*4*2

这太接近于不能成为整数的阶乘。现在让它等于2*a!是微不足道的。

直到现在我们得到一个可以被(a^2)!整除的数字,但是我们不知道这是否是最小的整数。

2a将是1s,2s,3s,4s,...,ns (a^2)!g! (a^2)!的两倍g!的最小值,2*a Connect-VIServer $server -User $user -Password $pwd $AllVirtualMachines = Get-VM -Location "Dev Machines" foreach ($VirtualMachine in $AllVirtualMachines) { Get-PassthroughDevice -VM $VirtualMachine | Remove-PassthroughDevice -Confirm:$false } foreach ($VirtualMachine in $AllVirtualMachines) { $PciDeviceList = Get-PassthroughDevice -VMHost 172.16.7.130 -Type Pci Add-PassthroughDevice -VM $VirtualMachine -PassthroughDevice $PciDeviceList[0] -Confirm:$false } foreach ($VirtualMachine in $AllVirtualMachines) { $PciDeviceList = Get-PassthroughDevice -VMHost 172.16.7.130 -Type Pci Add-PassthroughDevice -VM $VirtualMachine -PassthroughDevice $PciDeviceList[1] -Confirm:$false } foreach ($VirtualMachine in $AllVirtualMachines) { $PciDeviceList = Get-PassthroughDevice -VMHost 172.16.7.130 -Type Pci Add-PassthroughDevice -VM $VirtualMachine -PassthroughDevice $PciDeviceList[2] -Confirm:$false } foreach ($VirtualMachine in $AllVirtualMachines) { $PciDeviceList = Get-PassthroughDevice -VMHost 172.16.7.130 -Type Pci Add-PassthroughDevice -VM $VirtualMachine -PassthroughDevice $PciDeviceList[3] -Confirm:$false } componentDidMount所有这些INSERT INTO tbla (id, col1, col2, col3) SELECT id, col1, col2, col3 FROM tmp ON CONFLICT on constraint pkey_tbla DO UPDATE SET col1=tmp.col1 FROM tmp; DROP TABLE tmp; 除以{{1}} 1}}。这个论证证明{{1}}是最小的整数。

答案 1 :(得分:0)

  

有什么建议吗?

避免广泛的数学。

肯定会出现g >= a,所以......

a!g!的因子,a!square(a!)的因子,因此我们可以简化问题。将两边除以a!

g!/a! = 1 *  a+1 * a+2 * ... * g
square(a!)/a! = a!

现在找到g

的最小(a+1 * a+2 * ... * g) % a! == 0

这些a+1, a+2, ..., g个术语中的每一个都可能包含a!中的因子。在g到达2a之前,必须找到解决方案,但也许更快。找到每个术语时,将其从a!中分解出来并测试模态这样就可以将宽整数的需要降到最低。

如下所示。不幸的是我现在无法测试它。 IAC,OP正在寻找建议,而不是代码。

unsigned SOPP_LargeFactor(unsigned a) {
  unsigned i = 1;
  unsigned long long prod = 1;
  for (unsigned g=a+1; ; g++) {
    prod *= g;
    while (prod%i == 0) {
      if (i == a) return g;
      prod /= i;
      i++; 
    }
  }
}

答案 2 :(得分:0)

g!= k·a! 2 。在一些分解后,k =(a + 1)(a + 2)... g /(2 * 3 * 4 ... a)

如果k是整数,这意味着可以找到具有整数结果的除法。更多,所有分区必须是整数。

首先,将分子和分母分解为素数因子。即7! = 7·6·5·4·3·2 = 7·5·3 2 ·2 4

然后,如果g是一个解,所有分母因子也必须在分子中找到(例如,分子中的3 5 包括3 2 in denominator),因此可以取消。将分子中的其余因子相乘只需给出k,这是不需要的。

您可以设置一个循环来测试几个g,直到满足这个条件。我会存储素数及其指数,因此取消是指数减少的问题。

最后,不涉及 Big Number 计算。 g仅受sizeof(长)的限制。