原题地址
https://pintia.cn/problem-sets/1268384564738605056/problems/1294124786527993857
解题思路
没有用课堂上很复杂的结构体定义啥的~
注意到题目中给的都是严格的正整数(distinct positive integers
),所以就偷懒直接开了一个数组,初始状态所有元素为0,代表这个单元没有元素~
之后就常规操作就可以了!
注意事项
0.审题~题目的平方探测法只要正向的(with positive increments only
)。
1.查找位置时的更新写法。
正确写法类似
newPos = pos + pow(++cnum, 2);
一开始的时候忘记每次是在原来的pos基础上去加平方了!
2.注意特判n=1
的情况。
做的时候有一个测试点没过,是最小N
,也就是N=1
的时候。这里要注意,1
不是素数,但是我们求下一个素数的函数时,默认是直接判断该数的奇偶性,奇数+2
,偶数+1
,那么1
就比较特殊,1
只要+1
就可以得到比它大的素数2
了~
参考代码
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
typedef double db;
typedef long long LL;
typedef vector<int> VI;
const int inf = 2e9;
const LL INF = 8e18;
const int maxn = 5e5 + 5;
int* hashTable;
bool isPrime(int n) {
if (n <= 2) return false;
for (int i = (int)sqrt(n); i >= 2; i--) {
if (n % i == 0) return false;
}
return true;
}
int nextPrime(int n) {
if (n == 1) return 2; //1要特判
int p = (n % 2) ? n + 2 : n + 1; //p为奇数的话,+2,否则+1
int i;
while (1) {
for (i = (int)sqrt(p); i > 2; i--) { //因为p是奇数,故i>2即可
if (p % i == 0) break;
}
if (i == 2) break; //若循环结束,说明是素数
else p += 2;
}
return p;
}
int hashF(int key, int size) {
return key % size;
}
int find(int key, int size) {
int newPos, pos = hashF(key, size);
newPos = pos;
if (hashTable[pos]) { //若该位置有元素了
int cnum = 0;
while (hashTable[newPos]) {
newPos = pos + pow(++cnum, 2);
newPos %= size;
if (cnum > size) return -1;
}
return newPos;
} else return pos;
}
void insert(int key, int size) {
int pos = find(key, size);
if (pos != -1) {
hashTable[pos] = key;
printf("%d", pos);
}
else printf("-");
}
int main() {
int n, m, size;
scanf("%d%d", &n, &m);
if (isPrime(n)) size = n; //若n是素数,size直接等于n
else size = nextPrime(n);
hashTable = (int*)malloc(size * sizeof(int));
memset(hashTable, 0, sizeof(hashTable));
int k;
for (int i = 0; i < m; i++) {
if (i) printf(" ");
scanf("%d", &k);
insert(k, size);
}
return 0;
}