hdu 5207 hash统计

题目大意:求最大的两个数的最大公约数。

思路:数据范围较小,只有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快了不少。

你可能感兴趣的:(hash)