nyoj 找球号(二)

来源:互联网 发布:知乎飞机杯 编辑:程序博客网 时间:2024/05/01 18:58

找球号(二)

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

Input

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

Output

输出每次询问的结果"YES"或"NO".

Sample Input

2ADD 5 34 343 54 6 2QUERY 4 34 54 33 66

Sample Output

YESYESNONO
方法一(vector容器):
#include<stdio.h>#include<string.h>#include<vector>#include<algorithm>using namespace std;vector<bool>a(100000001);int main(){    char s[10];    int t;    scanf("%d",&t);    getchar();    while(t--)    {        int n,i,m;        memset(s,'\0',sizeof(s));        scanf("%s",s);        scanf("%d",&n);        if(!strcmp(s,"ADD"))        {            while(n--)            {                scanf("%d",&m);                a[m]=true;            }        }        else if(!strcmp(s,"QUERY"))        {            while(n--)            {                scanf("%d",&m);                printf(a[m]?"YES\n":"NO\n");            }        }    }    return 0;}
ps:这种方法还是比较好用的。。
方法二(Hash表):
  1. #include<iostream>  
  2. #include<cstdio>  
  3. #include<cstring>  
  4. #include<string>  
  5. #include<time.h>  
  6. #include<algorithm>  
  7. using namespace std;  
  8.   
  9. #define N 1000010  
  10. #define CLR(arr, what) memset(arr, what, sizeof(arr))  
  11.   
  12. const int fib = 111123;  
  13. int Key[N], Head[N], Next[N];  
  14. int top;  
  15.   
  16. void add(int n)  
  17. {  
  18.     int temp;  
  19.     temp = n % fib;  
  20.     Key[top] = n;  
  21.     Next[top] = Head[temp];  
  22.     Head[temp] = top;  
  23.     top++;  
  24. }  
  25.   
  26. int main()  
  27. {  
  28.     int ncase;  
  29.     char str[8];  
  30.     int num, number;  
  31.     bool flag;  
  32.     CLR(Key, 0);  
  33.     CLR(Head, -1);  
  34.     top = 0;  
  35.     flag = false;  
  36.     scanf("%d", &ncase);  
  37.     while(ncase--)  
  38.     {  
  39.         scanf("%s", str);  
  40.         if(str[0] == 'A')  
  41.         {  
  42.             scanf("%d", &num);  
  43.             for(int i = 0; i < num; ++i)  
  44.             {  
  45.                 scanf("%d", &number);  
  46.                 add(number);  
  47.             }  
  48.         }  
  49.         else  
  50.         {  
  51.             scanf("%d", &num);  
  52.             for(int i = 0; i < num; ++i)  
  53.             {  
  54.                 scanf("%d", &number);  
  55.                 int temp = number % fib;  
  56.                 for(int j = Head[temp]; j != -1; j = Next[j])  
  57.                     if(Key[j] == number)  
  58.                     {  
  59.                         flag = true;  
  60.                         break;  
  61.                     }  
  62.                 printf(flag == true ? "YES\n" : "NO\n");  
  63.                 flag = false;  
  64.             }  
  65.         }  
  66.     }  
  67.     return 0;  
  68. }  
ps:这种方法对我等小白来说有点难,待我先提升代码能力后再水此法。。
方法三(位存储水过):
  1. #include<stdio.h>    
  2. unsigned int hash[3125005] = {0};    
  3. int main()    
  4. {    
  5.     int i,a,t,n;    
  6.     char str[10];    
  7.     scanf("%d", &t);    
  8.     while(t--)    
  9.     {    
  10.         scanf("%s %d", str, &n);    
  11.         if(str[0] == 'A')    
  12.         {    
  13.             for(i = 0; i < n; ++i)    
  14.             {    
  15.                 scanf("%d", &a);    
  16.                 hash[a / 32] |= 1 << (a % 32);    
  17.             }    
  18.         }    
  19.         else if(str[0] == 'Q')    
  20.         {    
  21.             for(i = 0; i < n; ++i)    
  22.             {    
  23.                 scanf("%d", &a);    
  24.                 if(hash[a / 32] & (1 << (a % 32)))    
  25.                     printf("YES\n");    
  26.                 else    
  27.                     printf("NO\n");    
  28.             }    
  29.         }   
  30.     }  
  31.     return 0;    
  32. }    
ps:3125005怎么来的?因为最大值是10^7+10。用32来除法散列,(10^7+10)/32 ~~3125000.3125,所以取3125005。为什么是用32来散列呢?数据说了数值不会超过32位。
1 0
原创粉丝点击