zoukankan      html  css  js  c++  java
  • 找球号(Hash)

    题目:

    在某一国度里流行着一种游戏。游戏规则为:现有一堆球中,每个球上都有一个整数编号i(0<=i<=100000000),编号可重复,还有一个空箱子,现在有两种动作:一种是"ADD",表示向空箱子里放m(0<m<=100)个球,另一种是"QUERY”,表示说出M(0<M<=100)个随机整数ki(0<=ki<=100000100),分别判断编号为ki 的球是否在这个空箱子中(存在为"YES",否则为"NO"),先答出者为胜。现在有一个人想玩玩这个游戏,但他又很懒。他希望你能帮助他取得胜利。

     
    输入
    第一行有一个整数n(0<n<=10000);
    随后有n行;
    每行可能出现如下的任意一种形式:
    第一种:
    一个字符串"ADD",接着是一个整数m,随后有m个i;
    第二种:
    一个字符串"QUERY”,接着是一个整数M,随后有M个ki;

    输出
    输出每次询问的结果"YES"或"NO".
    样例输入
    2
    ADD 5 34 343 54 6 2
    QUERY 4 34 54 33 66
    样例输出
    YES
    YES
    NO
    NO

    分析:

    球号(1亿,并且可重复)非常的大!但是最多只有100个球,所以用一个大数组,下标(球号可重复)表示球号,内容标记是否存在,显然是不合理的。

    所以考虑用hash,hash就是将关键字和位置建立映射关系。但是不同的关键字可能对应到同一位置,这就是冲突,怎么处理冲突?方法很多。好的处理冲突的方法可以大大加速查找速度。我暂时只会用链地址法处理冲突。就是把关键字(可以存)当成链表头结点,如果后面算出的key和关键字相同,则插入到以关键字为头结点的那个链表中。所以一个链表的元素都是会对应同一个位置的(如果用数组),这样弄成链表(如果是数组,一个位置只能放一个数)就好查找了。

    hash就是插入和查找,插入的时候先查找,没找到才插,否则不用插。

    代码:

    #include<iostream>
    #include<cstdio>
    #define SIZE 1000001
    #define MOD 1000000
    //减小冲突的次数
     
    using namespace std;
    
    /* 感觉用链地址法处理hash冲突的话好像那个图的邻接表啊 */
    
    typedef struct node
    {
       int key;        
       struct node *next;
    }HashNode;
    
    HashNode hash[SIZE];//结构体数组存放链表头结点
    HashNode * search(HashNode head[SIZE],int k);//查找key的位置 
    void insert(HashNode head[SIZE],int k);//插入关键字k 
    
    int main()
    {
      int n,num,a,i;
      char ch[6];
      scanf("%d",&n); 
      for(i = 0 ; i != SIZE ; ++i)//将所有头结点初始化 
      {
          hash[i].key = -1;
          hash[i].next == NULL;      
      }    
      
        do
        {
          scanf("%s",ch);
          if(ch[0] == 'A')
          {
              scanf("%d",&num);
              for( i = 0 ; i != num ; ++i ) 
              {
                   scanf("%d",&a);
                   insert(hash,a);
              }      
          }            
          else
          {
              scanf("%d",&num);
              for( i = 0 ; i != num ; ++i )
              {
                   scanf("%d",&a);
                   if(search(hash,a))
                     puts("YES");
                   else             
                     puts("NO");      
              }
          }    
        
        }while(--n);
        
      //system("pause");
      return 0;    
    }
    
    HashNode * search(HashNode head[SIZE],int k)
    {
       HashNode *s ;
       int pos = k % MOD;//算出关键字的位置         
       s = & head[pos] ;  //让指针s指向这一链的头结点 
       while(s && s->key != k)//当当前结点不空,并且key未找到,就继续找,知道找到或者不存在为止 
         s = s->next;
     
      return s;//如果s 为空,则没找到,否则 查找成功 
    }
    
    void insert(HashNode head[SIZE],int k)
    {
         HashNode * q, *one;
         int pos;
         one = new HashNode;//开辟一个新结点 
         q = search(head,k);
         
         if(q)//如果找到,便不需要插入了 
          delete one;
         else//没找到,说明是新结点,可以插入 ,插在头结点的后面 
         {
            pos = k % MOD ;//算出关键字的位置 
            one->key =k;
            one->next = head[pos].next;
            head[pos].next = one;
         }
    }
    
  • 相关阅读:
    1002. Find Common Characters查找常用字符
    338. Counting Bits_比特位计数_简单动态规划
    Rail_UVa514_栈
    784. Letter Case Permutation C++字母大小写全排列
    C语言实现哈夫曼编码(最小堆,二叉树)
    559. Maximum Depth of N-ary Tree C++N叉树的最大深度
    27. Remove Element C++移除元素
    26. Remove Duplicates from Sorted Array C++ 删除排序数组中的重复项
    linux软件源配置
    linux 下安装 maven
  • 原文地址:https://www.cnblogs.com/HpuAcmer/p/2275131.html
Copyright © 2011-2022 走看看