hdu 5207 hash统计

本文介绍了一种求解最大两个数的最大公约数的方法。针对不超过10^5的数据范围,提供了两种算法实现:一是基于哈希表的方法,复杂度为n^1.5;二是采用类似筛法思想优化后的算法,复杂度为nlogn。

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

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

转载于:https://www.cnblogs.com/huoxiayu/p/4438411.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值