• BZOJ 2761 不重复的数字 哈希 or set or 二叉搜索树


       这是我第一次写哈希,感觉还好。虽然这道题今天一直在想用什么方法最好,一开始想过用 unique 这个函数, 想过 map ,想过 set,(刚才看别人题解的过程中,也有用treap写的,其实就是二叉搜索树) 但是map 和 set 查询都是 log n的,太慢了点。而且,我一直想学哈希,之所以一直没怎么学(只看了理论,没写过),有一个原因也是看过的哈希的代码太少(印象中只有紫书中的一篇和下文代码类似的,还有白书中基于哈希值的LCP),自己不好把握(这一次写,第一次交,就因为负数的问题,RE),最后就把他拿来做为 哈希 的第一道题了,加油,这是我朝哈希迈出的第一步。

    这是set的代码,一开始我还不知道set中怎么查询有没有一个值的存在。最后百度了才知道,唉,要加油啊!傻逼!(这份代码跑了700多毫秒)

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<set>
     4 #define rep(i,j,k) for(int i = j; i <= k; i++)
     5 #define maxn 50005
     6 using namespace std;
     7 
     8 set<int> s;
     9 int read()
    10 {
    11     int s = 0, t = 1; char c = getchar();
    12     while( !isdigit(c) ){
    13         if( c == '-' ) t = -1; c = getchar();
    14     }
    15     while( isdigit(c) ){
    16         s = s * 10 + c - '0'; c = getchar();
    17     }
    18     return s * t;
    19 }
    20 
    21 int main()
    22 {
    23     int t = read();
    24     while( t-- ){
    25         s.clear();
    26         int n = read();
    27         bool first = 1;
    28         rep(i,1,n){
    29             int x = read();
    30             if( !s.count(x) ){
    31                 if( first ) {
    32                     printf("%d", x);
    33                     first = 0; 
    34                 }
    35                 else printf(" %d", x);
    36                 s.insert(x);
    37             }
    38         }
    39         printf("
    ");
    40     }
    41     return 0;
    42 }

    这是哈希的代码,只跑了480毫秒

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #define rep(i,j,k) for(int i = j; i <= k; i++)
     5 #define maxn 100003
     6 #define mod 100003
     7 using namespace std;
     8 
     9 int head[maxn] = {0}, next[maxn] = {0};
    10 int num[maxn] = {0}; 
    11 
    12 int read()
    13 {
    14     int s = 0, t = 1; char c = getchar();
    15     while( !isdigit(c) ){
    16         if( c == '-' ) t = -1; c = getchar();
    17     }
    18     while( isdigit(c) ){
    19         s = s * 10 + c - '0'; c = getchar();
    20     }
    21     return s * t;
    22 }
    23 
    24 int try_to_insert(int s)
    25 {
    26     int h = num[s] % mod;  if( h < 0 ) h = -h; 
    27     int u = head[h];
    28     while( u ){
    29         if( num[u] == num[s] ) return 0;
    30         u = next[u];
    31     }
    32     next[s] = head[h];
    33     head[h] = s;
    34     return 1;
    35 }
    36 
    37 int main()
    38 {
    39     int t = read();
    40     while( t-- ){
    41         memset(head,0,sizeof(head));
    42         int n = read();
    43         bool first = 1;
    44         rep(i,1,n){
    45             num[i] = read();
    46             if( try_to_insert(i) ){
    47                 if( first ) {
    48                     printf("%d", num[i]);
    49                     first = 0; 
    50                 }
    51                 else printf(" %d", num[i]);
    52             }
    53         }
    54         printf("
    ");
    55     }
    56     return 0;
    57 }

    2761: [JLOI2011]不重复数字

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 3089  Solved: 1143
    [Submit][Status][Discuss]

    Description

    给出N个数,要求把其中重复的去掉,只保留第一次出现的数。
    例如,给出的数为1 2 18 3 3 19 2 3 6 5 4,其中2和3有重复,去除后的结果为1 2 18 3 19 6 5 4。
     

    Input

    输入第一行为正整数T,表示有T组数据。
    接下来每组数据包括两行,第一行为正整数N,表示有N个数。第二行为要去重的N个正整数。
     

    Output

     
    对于每组数据,输出一行,为去重后剩下的数字,数字之间用一个空格隔开。

    Sample Input

    2
    11
    1 2 18 3 3 19 2 3 6 5 4
    6
    1 2 3 4 5 6

    Sample Output

    1 2 18 3 19 6 5 4
    1 2 3 4 5 6

    HINT

    对于30%的数据,1 <= N <= 100,给出的数不大于100,均为非负整数;


    对于50%的数据,1 <= N <= 10000,给出的数不大于10000,均为非负整数;


    对于100%的数据,1 <= N <= 50000,给出的数在32位有符号整数范围内。


    提示:


    由于数据量很大,使用C++的同学请使用scanf和printf来进行输入输出操作,以免浪费不必要的时间。

     

    人一我十,人十我万!追逐青春的梦想,怀着自信的心,永不放弃!仿佛已看到希望,尽管还在远方
  • 相关阅读:
    模式识别及相关领域的重要期刊列表转载
    Spotify敏捷模式详解三部曲第三篇:工程文化
    Spotify敏捷模式详解三部曲第二篇:研发过程
    Scrum工具Leanoo思维导图
    真心推荐的项目管理工具
    Spotify敏捷模式详解三部曲第一篇:研发团队
    敏捷开发必须要选的scrum工具
    什么是用户故事?用Leangoo怎么管理?
    Scrum工具Leangoo“免费版”与“企业版”对比
    参加scrum中文网ScrumMaster认证培训
  • 原文地址:https://www.cnblogs.com/83131yyl/p/5080706.html
Copyright © 2020-2023  润新知