1078ハッシング(25分)
この問題のタスクは単純です。一連の明確な正の整数をハッシュテーブルに挿入し、入力数値の位置を出力します。ハッシュ関数はH(key)= key%TSizeとして定義されます。TSizeはハッシュテーブルの最大サイズです。二次プローブ(正の増分のみを使用)は、衝突を解決するために使用されます。
テーブルのサイズは素数よりも優れていることに注意してください。ユーザーが指定した最大サイズが素数でない場合は、ユーザーが指定したサイズよりも大きい最小の素数になるようにテーブルサイズを再定義する必要があります。
入力仕様:
各入力ファイルには1つのテストケースが含まれます。MSIZE(≤10:それぞれの場合のために、最初の行は、2つの正の数含ま
4
)とN(≤MSize)それぞれのユーザー定義テーブルのサイズと、入力番号の数、です。次に、次の行にN個の異なる正の整数を指定します。行内のすべての数値はスペースで区切られています。
出力仕様:
各テストケースについて、入力番号の対応する位置(インデックスは0から始まります)を1行に出力します。行内のすべての数字はスペースで区切られており、行の終わりに余分なスペースがあってはなりません。数字を挿入できない場合は、代わりに「-」を印刷してください。
入力例:
4 4
10 6 4 15
出力例:
0 1 4 -
問題解決
ハッシュテーブルサイズM(M以上の素数に変換)
、数値Nを指定、
各数値を順番に格納した後に添字を出力
二次検出方法に注意してください。+ tの2乗を試みるたびに、境界条件はt <M / 2になります。この時点で保存する場所が見つからない場合は、保存できないことを意味します。
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
bool isPrim(int n)
{
if(n<2) return false;
if(n==2) return true;
for(int i=2;i<=sqrt(n);i++)
if(n%i==0) return false;
return true;
}
int nextPrim(int n)
{//素数
//不能被2——根号n的所有数整除的数
while(!isPrim(n))
++n;
return n;
}
const int maxN=10010;
int M,N;
int Hash[maxN];
void input()
{
cin>>M>>N;
M=nextPrim(M);
fill(Hash,Hash+M,-1); //全部置为-1
int tmp;
for(int i=0;i<N;i++)
{
cin>>tmp;
int t=0;
int index= tmp%M;
int flag=0;
while(t<M)
{
t++;
if(Hash[index]==-1){
Hash[index]=tmp;
cout<<index;
flag=1;
break;
}
else
index=(tmp%M+t*t)%M;
}
if(flag==0)
cout<<"-";
if(i!=N-1)
cout<<" ";
}
}
int main()
{
input();
}