zoukankan      html  css  js  c++  java
  • 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
    ", _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
    ", _case, solve(maxn));
    45     }
    46     return 0;
    47 }

    复杂度:nlogn

    类似于筛法的思想进行优化,比解法1快了不少。

  • 相关阅读:
    自定义vue必填验证指令
    福珑2日常存活策略
    树莓派系统安装和配置 WiringPi
    代码实现RabbitMQ死信队列的创建
    博客已经搬家
    浅谈PHP序列化与反序列化
    prometheus监控golang服务实践
    ETCD核心机制解析
    N1BOOK 记录
    利用Ubuntu虚拟机制作F2FS文件系统镜像
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4438411.html
Copyright © 2011-2022 走看看