题意:
给定一个序列,用平方探测法解决哈希冲突,然后给出m个数字,如果这个数字不能够被插入就输出”X cannot be inserted.”,然后输出这m个数字的平均查找时间
思路:
抽空整套做了一下寒假最新的这套题,感觉还行,大概一个半小时能写完,但是这题就卡住了,前面也出现过这种问题,主要问题在于我数据结构里学的平方探测法定义就不一样,PAT里递推公式为Hi=(key+di)%m,其中key是不随碰撞变换的,也就是一开始就确定了,然后平方探测法中di是k^2,书上k的范围是[1,n/2],但是PAT里一般是[0,n-1]。这题表述的也很不清楚,测定搜索次数的时候,如果碰到空白区域也是直接退出。还有这题我一开始是用map写的,会出现一些问题,比如如果map[num]中num没有先插入,访问是会出现问题,这点要注意。
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
using namespace std;
const int maxn = 10050;
int n, m, k;
int input[maxn], check[maxn];
int vis[maxn];
bool isPrime(int x) {
if (x <= 1)
return false;
else {
for (int i = 2; i*i <= x; i++) {
if (x%i == 0) {
return false;
}
}
}
return true;
}
int main() {
scanf("%d%d%d", &n, &m, &k);
while (!isPrime(n)) {
n++;
}
for (int i = 0; i < m; i++) {
scanf("%d", &input[i]);
int num = input[i];
bool flag = true;
for (int j = 0; j < n; j++) {
num = (input[i] + j*j) % n;
if (vis[num] == 0) {
vis[num] = input[i];
flag = false;
break;
}
}
if (flag) {
printf("%d cannot be inserted.\n", input[i]);
}
}
double sum = 0.0;
for (int i = 0; i < k; i++) {
scanf("%d", &check[i]);
int cnt = 1;
for (int j = 0; j < n; j++) {
int num = (check[i] + j*j) % n;
if (vis[num] == check[i] || vis[num] == 0)
break;
cnt++;
}
sum += cnt;
}
printf("%.1lf\n", sum / k);
return 0;
}