题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805389634158592
首先题目的意思大概是:给出散列表Tsize和欲插入的元素,讲这些元素按照读入的顺序插入到散列表中。解决元素放置冲图的办法是:只往正向增加的二次探查法。如果给出的Tsize不是素数,则需要将Tsize变成一个比Tsize大的死一个素数。
这道题目思想上没什么难点,但是细节很容易出问题,自己就一直卡在12分,得不到满分,重新按照自己的思路写了一遍AC了。
一下是完整代码:
二次探查法:
(后续再补充)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int arr[maxn];
bool flag[maxn]; //怕放在main函数里面定义会溢出,所以放在外面了
bool isPrime(int num)
{
//判断num是不是素数(模板,无需多解释了)
if(num <= 1)
return false;
for(int i = 2; i <=(int)sqrt(num*1.0);i++)
{
if(num%i == 0)
return false;
}
return true;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i = 0; i < m; i++)
scanf("%d",&arr[i]);
memset(flag,false,sizeof(flag));
//如果n不是素数,寻找第一个比n大的素数
while(isPrime(n) == false)
{
n++;
}
for(int i = 0; i < m; i++)
{
为数组里面的每个元素寻找位置
int temp = arr[i]%n;
if(flag[temp] == false)
{
flag[temp] = true;
if(i == 0)
printf("%d",temp);
else
printf(" %d",temp);
}
else
{
//如果没寻找到位置(即存在位置冲突),则用正向增加的二次探查法继续寻找
int step;
for(step = 1; step < n; step++)
{
int ans = (arr[i] + step * step)%n;
if(flag[ans] == false)
{
flag[ans] = true;
if(i == 0)
printf("%d",ans);
else
printf(" %d",ans);
break;
}
}
if(step >= n)
{
//经过以上两步还未寻找到,就打印‘-’
printf(" -");
}
}
}
printf("\n");
return 0;
}