HDU 5207 Greatest Greatest Common Divisor
题目链接:
hdu:http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=153598
bc(中文):http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=577&pid=1002
题解:
1、对于每个输入,枚举它的因子,并统计,结果存在mmp数组中,最后再倒过来扫一遍mmp数组,其中第一个mmp[i]>=2的,就是答案。
时间复杂度:O(n*sqrt(n) )
这个跑了1404ms
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 6 const int maxn=1e5+10; 7 typedef long long LL; 8 9 int n; 10 int mmp[maxn]; 11 12 void init(){ 13 memset(mmp,0,sizeof(mmp)); 14 } 15 16 int main() { 17 int tc,kase=0; 18 scanf("%d",&tc); 19 while(tc--) { 20 scanf("%d",&n); 21 init(); 22 for(int i=0;i<n;i++){ 23 int x; 24 scanf("%d",&x); 25 for(int div=1;div*div<=x;div++){ 26 if(x%div==0){ 27 mmp[div]++; 28 if(x/div!=div) mmp[x/div]++; 29 } 30 } 31 } 32 int ans=1; 33 for(int i=maxn-1;i>=0;i--){ 34 if(mmp[i]>=2){ 35 ans=i; break; 36 } 37 } 38 printf("Case #%d: %d\n",++kase,ans); 39 } 40 return 0; 41 }
2、用筛法预处理出10^5以内所有数的因子,然后采用同上的方法做。
筛法的时间复杂度:O(n+n/2+n/3+n/4+...n/n)=O(n*(1+1/2+1/3+...1/n))=O(n*logn)
(附:欧拉公式:1+1/2+1/3+……+1/n=ln(n)+C)
这个跑了374ms
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 7 const int maxn=1e5+10; 8 typedef long long LL; 9 10 int n; 11 int mmp[maxn]; 12 vector<int> Div[maxn]; 13 14 void pre_for_div(){ 15 for(int i=1;i<maxn;i++){ 16 for(int t=i;t<maxn;t+=i){ 17 Div[t].push_back(i); 18 } 19 } 20 } 21 22 void init(){ 23 memset(mmp,0,sizeof(mmp)); 24 } 25 26 int main() { 27 pre_for_div(); 28 int tc,kase=0; 29 scanf("%d",&tc); 30 while(tc--) { 31 scanf("%d",&n); 32 init(); 33 for(int i=0;i<n;i++){ 34 int x; 35 scanf("%d",&x); 36 for(int j=0;j<Div[x].size();j++){ 37 mmp[Div[x][j]]++; 38 } 39 } 40 int ans=1; 41 for(int i=maxn-1;i>=0;i--){ 42 if(mmp[i]>=2){ 43 ans=i; break; 44 } 45 } 46 printf("Case #%d: %d\n",++kase,ans); 47 } 48 return 0; 49 }
3、先统计每个输入的值出现的个数,存在cnt里面;然后从大到小枚举答案ans=d,求解sum(cnt[d],cnt[d*2],cnt[d*3]...),如果sum>=2说明答案就是d。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 7 const int maxn=1e5+10; 8 typedef long long LL; 9 10 int n; 11 int cnt[maxn]; 12 13 void init(){ 14 memset(cnt,0,sizeof(cnt)); 15 } 16 17 int main() { 18 int tc,kase=0; 19 scanf("%d",&tc); 20 while(tc--) { 21 scanf("%d",&n); 22 init(); 23 for(int i=0;i<n;i++){ 24 int x; 25 scanf("%d",&x); 26 cnt[x]++; 27 } 28 int ans=1; 29 for(int g=maxn-1;g>=1;g--){ 30 int tmp=0; 31 for(int sum=g;sum<maxn;sum+=g){ 32 tmp+=cnt[sum]; 33 } 34 if(tmp>=2){ 35 ans=g; break; 36 } 37 } 38 printf("Case #%d: %d\n",++kase,ans); 39 } 40 return 0; 41 }