PAT (Advanced Level) Practice 1078 Hashing (25 分)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Nightmare_ak/article/details/84347938

哈希表二次探测法,即一次判断(p+k2)%n,k=0…n-1,到n-1就可以了,因为之后会出现循环,证明的话就是:(n+i)2%n=(n2+2*n*i+i2)%n=i2%n

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

const int N=1e5+5;

int prime[N],pnum,notp[N],vis[N],revis[N];

void sieve()
{
    for(int i=2;i<N;i++)
    {
        if(!notp[i]) prime[pnum++]=i;
        for(int j=0;j<pnum&&prime[j]*i<N;j++)
        {
            notp[prime[j]*i]=1;
            if(i%prime[j]==0) break;
        }
    }
}

int main()
{
    sieve();
    int sz,n;
    scanf("%d%d",&sz,&n);
    sz=prime[lower_bound(prime,prime+pnum,sz)-prime];
    for(int i=1;i<=n;i++)
    {
        int x;scanf("%d",&x);
        if(i!=1) printf(" ");
        int flag=0;
        for(int j=0;;j++)
        {
            int xx=(x+1LL*j*j)%sz;
            if(!vis[xx])
            {
                vis[xx]=1;
                printf("%d",xx);
                flag=1;
                break;
            }
            if(revis[xx]==i) break;
            revis[xx]=i;
        }
        if(!flag) printf("-");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Nightmare_ak/article/details/84347938