题目:https://pintia.cn/problem-sets/15/problems/890
给定数字n和m,分别代表字符串数量和散列表长度,输出n个字符串,要求输出每个字字符串的坐标。
坐标的计算方法为将每个字符串的后3位映射为整数,映射公式为:
倒数第一位+倒数第二位*32+倒数第三位*32*32的和sum,取sum%m的值为每个字符串的坐标,
若有冲突,则取sum+flag*flag(flag=1,2,3...),sum-flag*flag(flag=1,2,3...),两个值求余m,取m为每个字符串的坐标。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 1999
#define MAXNUM -100
typedef long long ll;
typedef struct{
char data[9];
}Hash;
int n,m;
int main(){
Hash ha[MAX];
char ch[9];
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
strcpy(ha[i].data,"NULL");
for(int i=0;i<n;i++){
scanf("%s",ch);
int len=strlen(ch)-1,j=1;
int sum=0,flag=1;
for(;len>=0&&j<4;j++,len--,flag*=32)
sum+=(ch[len]-'A')*flag;
int index;
for(int flag=0;;flag++){
index=(sum+flag*flag)%m;
if(!strcmp(ha[index].data,"NULL")||!strcmp(ha[index].data,ch))
break;
int tmp=sum-flag*flag;
while(tmp<0)
tmp+=m;
index=tmp%m;
if(!strcmp(ha[index].data,"NULL")||!strcmp(ha[index].data,ch))
break;
}
strcpy(ha[index].data,ch);
if(i) printf(" ");
printf("%d",index);
}
}