题目大意:求最大的两个数的最大公约数。
思路:数据范围较小,只有10^5,可以考虑哈希。
解法1:
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 100001; 7 int hash_table[N]; 8 int a[N]; 9 int n; 10 11 void set( int x ) 12 { 13 int i; 14 for ( i = 1; i * i < x; i++ ) 15 { 16 if ( x % i == 0 ) 17 { 18 hash_table[i]++; 19 hash_table[x / i]++; 20 } 21 } 22 if ( i * i == x ) hash_table[i]++; 23 } 24 25 int solve() 26 { 27 for ( int i = N - 1; i > 0; i-- ) 28 { 29 if ( hash_table[i] >= 2 ) 30 { 31 return i; 32 } 33 } 34 } 35 36 int main () 37 { 38 int t; 39 scanf("%d", &t); 40 for ( int _case = 1; _case <= t; _case++ ) 41 { 42 scanf("%d", &n); 43 for ( int i = 0; i < n; i++ ) 44 { 45 scanf("%d", a + i); 46 } 47 memset( hash_table, 0, sizeof(hash_table) ); 48 for ( int i = 0; i < n; i++ ) 49 { 50 set(a[i]); 51 } 52 printf("Case #%d: %d\n", _case, solve()); 53 } 54 return 0; 55 }
复杂度:n ^ 1.5
解法2:
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 100001; 7 int cnt[N]; 8 int mark[N]; 9 int a[N]; 10 int n; 11 12 int solve( int r ) 13 { 14 for ( int i = r; i > 0; i-- ) 15 { 16 if ( cnt[i] >= 2 ) return i; 17 } 18 } 19 20 int main () 21 { 22 int t; 23 scanf("%d", &t); 24 for ( int _case = 1; _case <= t; _case++ ) 25 { 26 scanf("%d", &n); 27 int maxn = -1; 28 memset( mark, 0, sizeof(mark) ); 29 for ( int i = 0; i < n; i++ ) 30 { 31 scanf("%d", a + i); 32 mark[a[i]]++; 33 if ( a[i] > maxn ) maxn = a[i]; 34 } 35 memset( cnt, 0, sizeof(cnt) ); 36 for ( int i = 2; i <= maxn; i++ ) 37 { 38 for ( int j = i; j <= maxn; j += i ) 39 { 40 cnt[i] += mark[j]; 41 } 42 } 43 cnt[1] = 2; 44 printf("Case #%d: %d\n", _case, solve(maxn)); 45 } 46 return 0; 47 }
复杂度:nlogn
类似于筛法的思想进行优化,比解法1快了不少。
原文:http://www.cnblogs.com/huoxiayu/p/4438411.html