[英]c++ large numbers in factorial
我正在嘗試制作一個問題的程序“給定一個正整數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;
}
對於值大於20的所有輸入,蠻力將導致整數溢出。我得到了一個更好的解決方案,其時間復雜度為O(T)
,其中T = number of test cases
並使用常量空間。
解決方案: 對於所有a, g
值將等於2*a
a 。
(a!)^2 = (a!)*a*(a-1)*(a-2)*..3*2*1
我們的目標是以g!
的形式制作(a!)*a*(a-1)*(a-2)*..3*2*1
g!
乘以所需的最小可能整數。
如果我們乘2
與各a,a-1,a-2,...,3,2,1
,那么我們將得到
(a!)*2a*(2a-2)*(2a-4)*..6*4*2
這太接近而不能成為整數的階乘。 現在讓它等於2*a!
是微不足道2*a!
。
直到現在我們得到一個可以被(a^2)!
整除的數字(a^2)!
但是我們不知道這是否會是最小的整數。
這個2a
將是最小的數字,因為你在(a^2)!
有兩次1s,2s,3s,4s,...,ns
(a^2)!
所有這些應該存在於g!
as (a^2)!
划分g!
。 這個論證證明2*a
是最小的這樣的整數。
有什么建議么?
避免廣泛的數學。
肯定會出現g >= a
,所以....
a!
是g!
一個因素g!
和a!
是一個square(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! == 0
這些a+1, a+2, ..., g
中的每a!
都可能有一個因素a!
。 必須在時間g
達到2a
時找到解決方案,但可能更快。 隨着每個術語的發現,將其排除在外a!
並測試mod-ness這使得對寬整數的需求降至最低。
像下面這樣的東西。 不幸的是我現在無法測試它。 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++;
}
}
}
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 ),因此可以取消。 將分子中的其余因子相乘只需給出k,這是不需要的。
您可以設置循環以測試幾個g,直到滿足此條件。 我會存儲素數及其指數,因此取消是指數減少的問題。
最后,不涉及大數計算。 g僅受sizeof(long)的限制。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.