目錄
1,題目描述
Sample Input:
4 5 4
10 6 4 15 11
11 4 15 2
Sample Output:
15 cannot be inserted.
2.8
題目描述
先在哈希表中插入一些數據,然後給出一系列數據進行查找(找到/不存在),並求出平均查找次數;
2,思路
算法
- 確定MSize,就是尋找比初始MSize大的最小質數:
- 向哈希表中插入數據:
- 計算每次查找的次數:
3,AC代碼
#include<bits/stdc++.h>
using namespace std;
int MSize, N, M, table[20005], num; // !!!10005不夠
bool isPrime(int x){
if(x <= 1) return false;
for(int i = 2; i <= sqrt(x); i++)
if(x % i == 0)
return false;
return true;
}
void insert(const int x){
int i, pos;
for(i = 0; i < MSize; i++){
pos = (x + i * i) % MSize;
if(table[pos] == 0){
table[pos] = x;
break;
}
}
if(table[pos] != x){
printf("%d cannot be inserted.\n", x);
}
}
int find(const int x){
int i, pos;
for(i = 0; i < MSize; i++){
pos = (x + i * i) % MSize;
if(table[pos] == x || table[pos] == 0){// !!!注意條件
break;
}
}
return i + 1;
}
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
scanf("%d%d%d", &MSize, &N, &M);
while(!isPrime(MSize)) MSize++;
for(int i = 0; i < N; i++){
scanf("%d", &num);
insert(num);
}
double sum = 0;
for(int i = 0; i < M; i++){
scanf("%d", &num);
sum += find(num);
}
printf("%.1f", sum * 1.0 / M);
return 0;
}
4,解題過程
第一搏
和@&再見螢火蟲& 【PAT_甲級_1078 Hashing (25point(s)) (C++)【哈希表/平方探測法】】這題很像,於是不假思索:
#include<bits/stdc++.h>
using namespace std;
int MSize, N, M, table[10005], num;
bool isPrime(int x){
if(x <= 1) return false;
for(int i = 2; i <= sqrt(x); i++)
if(x % i == 0)
return false;
return true;
}
void insert(int num){
int i;
for(i = 0; i < MSize; i++){
int pos = (num + i * i) % MSize;
if(table[pos] == 0){
table[pos] = num;
break;
}
}
if(i == MSize){
printf("%d cannot be inserted.\n", num);
}
}
int find(int num){
int i;
for(i = 0; i < MSize; i++){
int pos = (num + i * i) % MSize;
if(table[pos] == num || table[pos] == 0){// !!!注意條件
return i + 1;
}
}
return i + 1;
}
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
scanf("%d%d%d", &MSize, &N, &M);
while(!isPrime(MSize)) MSize++;
for(int i = 0; i < N; i++){
scanf("%d", &num);
insert(num);
}
double sum = 0;
for(int i = 0; i < M; i++){
scanf("%d", &num);
//cout<<num <<' '<<find(num)<<endl;
sum += find(num);
}
printf("%.1f", sum / M);
return 0;
}
第二搏
這類題目的細節需要特別的注意!
查閱了其他大佬的做法之後,注意到兩點:
1,在插入/查找的時候是否需要到達MSize?
經過測試,發現不到MSize也是可以通過的。
2,table初始大小的設計:
爲了簡化main函數的內容,使代碼結構更清晰,我採用了設計函數的方法,插入數據爲insert,查找數據爲find;
爲了減少函數的參數,將table數組放在了全局變量,因而必須提前定下大小(不能等MSize最終值計算出來之後再設置大小);
一開始規模爲10000,所以我就設置大小爲10005,如第一次測試,於是我乾脆把規模改爲20005,終於通過了(o゜▽゜)o☆[BINGO!]