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;
         }
    }
    
  • 相关阅读:
    spark streaming 概述
    spark sql 的性能调优
    LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal (用中序和后序树遍历来建立二叉树)
    LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal (用先序和中序树遍历来建立二叉树)
    LeetCode 90. Subsets II (子集合之二)
    LeetCode 88. Merge Sorted Array(合并有序数组)
    LeetCode 81. Search in Rotated Sorted Array II(在旋转有序序列中搜索之二)
    LeetCode 80. Remove Duplicates from Sorted Array II (从有序序列里移除重复项之二)
    LeetCode 79. Word Search(单词搜索)
    LeetCode 78. Subsets(子集合)
  • 原文地址:https://www.cnblogs.com/HpuAcmer/p/2275131.html
Copyright © 2011-2022 走看看