目录
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!]