PAT甲级 1145 哈希 - 平均查找时间

原题链接

这个问题的任务很简单:

首先将一个由若干个不同正整数构成的整数序列插入到一个哈希表中,然后尝试从表中查找另一个整数键值序列,并输出平均查找时间(查找时间指查找某个值是否在表中所进行的比较操作的次数)。

哈希函数定义为 H(key)=key%TSize,其中 TSize 是哈希表的最大大小。

利用只具有正增量的二次探测法来解决冲突。

注意,哈希表的大小最好是素数,如果用户给出的最大大小不是素数,则必须将表大小重新定义为大于用户给出的大小的最小素数。

输入格式
第一行包含三个正整数 MSize,N,M,分别表示用户定义的表的大小,插入整数的数量,查找键值的数量。

第二行包含 N 个不同的正整数,表示插入序列。

第三行包含 M 个正整数,表示键值序列。

同行数字之间用空格隔开,两个序列中包含的整数均不超过 105。

输出格式
如果无法插入一些数字,则将其按顺序以如下格式输出,每个数字占一行:

X cannot be inserted.
其中 X 表示无法插入的数字。

最后一行输出 M 次查找的平均查找时间,保留一位小数。

注意: 如果查找了 TSize 次,每次查找的位置上均有数,但都不等于要查找的数,则认为查找时间是 TSize+1。

数据范围
1≤MSize,N,M≤104
输入样例:
4 5 4
10 6 4 15 11
11 4 15 2
输出样例:
15 cannot be inserted.
2.8

我的解法:

#include <bits/stdc++.h>
using namespace std;

const int N = 10010;
int n, m, s;
int h[N];

bool is_prime(int n){
    if(n == 1) return false;
    for(int i = 2; i * i <= n; i ++ ){
        if(n % i == 0) return false;
    }
    return true;
}

int find(int x, int &count){
    int t = x % s;
    for(int i = 0; i < s; i ++ ){
        int j = (t + i * i) % s;
        if(h[j] == 0 || h[j] == x) return j;
        else count ++ ;
    }
    return -1;
}

int main(){
    cin >> s >> n >> m;
    while(!is_prime(s)) s ++;
    
    for(int i = 0; i < n; i ++ ){
        int x, count = 1;
        cin >> x;
        int t = find(x, count);
        
        if(t == -1) printf("%d cannot be inserted.\n", x);
        else h[t] = x;
    }
    
    int cnt = 0;
    for(int i = 0; i < m; i ++ ){
        int x, count = 1;
        cin >> x;
        int t = find(x, count);
        cnt += count;
    }
    printf("%.1lf", (double) cnt / m);
    return 0;
}

收获:

哈希查找和存值用同一个函数

猜你喜欢

转载自blog.csdn.net/weixin_45660485/article/details/126072059