求兩個超級大數的最大公約數


由於給出的數太大了,所以我們將兩個數A,B拆成了N個數相乘和M個數相乘的形式。N,M<=1000,拆成的數<=1000000000。是不是夠大?

最終的結果最多保留9位輸出。

 

例如:

3
358572 83391967 82
3
50229961 1091444 8863

輸出為:

000012028

 

根據歐拉公式,我們可以將任何一個數表示成如下形式:

n=p1^x1*p2^x2*p3^x3.......*pm^xm;

 

如果將A和B分別表示成

A = p1^a1 * p2^a2 * … * pn^an

B = p1^b1 * p2^b2 * … * pn^bn

其中p1,p2....都是素數,a1,a2...都是整數

那么

GCD( A, B ) = p1^min(a1,b1) * p2^min(a2,b2) * … * pn^min(an,bn)。

 

對於任何一個整數,我們可以快速的將它因式分解

scanf("%d",&a);
for(j=2;j*j<=a;j++)
{
    while(a%j==0)
        a/=j,A[j]++;
}
if(a>1)
    A[a]++;

對於這樣由N個數乘積組成的數,我們可以將N個數的拆分結果全部保存在同一個A數組中,最終的結果就是超大數自身的拆分。
還有一個需要注意的是,給出的a<=1000000000,直接開數組內存上和時間上都很吃力,所以推薦用map<int,int>容器。

 

View Code
 1 #include<iostream>
 2 #include<string>
 3 #include<map>
 4 using namespace std;
 5 #define mod 1000000000
 6 
 7 map<int,int>A,B;
 8 int n,m,a;
 9 __int64 ans;
10 
11 int min(int a,int b)
12 {
13     return a<b?a:b;
14 }
15 
16 int main()
17 {
18     int i,j;
19     freopen("D:\\in.txt","r",stdin);
20     while(scanf("%d",&n)==1)
21     {
22         A.clear();B.clear();
23         for(i=0;i<n;i++)
24         {
25             scanf("%d",&a);
26             for(j=2;j*j<=a;j++)
27             {
28                 while(a%j==0)
29                     a/=j,A[j]++;
30             }
31             if(a>1)
32                 A[a]++;
33         }
34         scanf("%d",&m);
35         for(i=0;i<m;i++)
36         {
37             scanf("%d",&a);
38             for(j=2;j*j<=a;j++)
39             {
40                 while(a%j==0)
41                     a/=j,B[j]++;
42             }
43             if(a>1)
44                 B[a]++;
45         }
46         ans=1;
47         int flag=0;
48         map<int,int>::iterator it;
49         for(it=A.begin();it!=A.end();it++)
50         {
51             if(B.count(it->first))
52             {
53                 int p=it->first;
54                 int r=min(A[p],B[p]);
55                 for(i=0;i<r;i++)
56                 {
57                     ans*=p;
58                     if(ans>=mod)
59                     {
60                         ans%=mod;
61                         flag=1;
62                     }
63                 }
64             }
65         }
66         if(flag)
67             printf("%09d\n",(int)ans);
68         else
69             printf("%I64d\n",ans);
70     }
71     return 0;
72 }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM