nyist oj 138 找球號(二)(hash 表+位運算)
阿新 • • 發佈:2017-06-16
pan char s geo 運算 arch font msu 哈希 next
找球號(二)
時間限制:1000 ms | 內存限制:65535 KB 難度:5- 描寫敘述
-
在某一國度裏流行著一種遊戲。遊戲規則為:現有一堆球中。每一個球上都有一個整數編號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
- 來源
- [苗棟棟]原創
-
上傳者
苗棟棟
hash表的入門題,開始都沒接觸過用hash做的題。學數據結構的時候。這個內容也僅僅是粗略的看了一下。沒有細致去研究過,看到這道題的提示,就去把hash表的內容細致的看了一遍
hash表的優勢就在於高速的插入和查詢大量的數據,哈希表也有一些缺點它是基於數組的,數組創建後難於擴展某些哈希表被基本填滿時,性能下降得很嚴重。所以程序雖必需要清楚表中將要存儲多少數據(或者準備好定期地把數據轉移到更大的哈希表中,這是個費時的過程)。所以這道題目假設數組開的小了。就會超時。
以下是代碼:
#include <stdio.h> #include <string.h> const int maxn=1000002; const int fib=111123;//這個值是參考別人的好像和斐波拉契有關 int Hash[maxn],head[maxn],next[maxn];//head相當於每個散列表的頭節點,當前節點的下一個節點 int top; void add(int m)//插入元素 { int key=m%fib; next[top]=head[key]; head[key]=top; Hash[top]=m; top++; } bool query(int m)//查詢元素 { int key=m%fib; for(int i=head[key];i>-1;i=next[i]) { if(Hash[i]==m) return true; } return false; } int main() { int n,m,num; char s[5]; scanf("%d",&n); memset(head,-1,sizeof(head));//賦初值為-1; top=0;//這裏要寫在外面,先前寫在循環裏面,超時了好多次。由於僅僅是建了一個hash表 while(n--) { scanf("%s %d",s,&m); if(s[0]==‘A‘) { for(int i=0;i<m;i++) { scanf("%d",&num); add(num); } } else { for(int i=0;i<m;i++) { scanf("%d",&num); if(query(num)) printf("YES\n"); else printf("NO\n"); } } } return 0; }
3125005怎麽來的?由於最大值是10^7+10。
用32來除法散列。(10^7+10)/32 ~~3125000.3125。所以取3125005。為什麽是用32來散列呢?數據說了數值不會超過32位。
hash表也是基於位運算的原理。
以下是代碼;
#include <cstdio> #include <cstring> int Hash[3125005]={0}; int main() { int n,m,num; char s[5]; scanf("%d",&n); while(n--) { scanf("%s %d",s,&m); if(s[0]==‘A‘) { for(int i=0;i<m;i++) { scanf("%d",&num); Hash[num / 32] |= 1 << (num % 32); } } else { for(int i=0;i<m;i++) { scanf("%d",&num); if(Hash[num / 32] & (1 << (num % 32))) printf("YES\n"); else printf("NO\n"); } } } return 0; }
nyist oj 138 找球號(二)(hash 表+位運算)