[JLOI2011]不重复数字

Posted zzrblogs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JLOI2011]不重复数字相关的知识,希望对你有一定的参考价值。

原题链接 https://www.luogu.org/problemnew/show/P4305

 

题解

题目大意:
给出N个数,要求把其中重复的去掉,只保留第一次出现的数。
最后按顺序输出
N <= 50000

然这题是个哈希的典型题目

HASH,我对于它的理解就是一个桶%一个数,当然并不是如此,有很多更好的HASH函数可以更好的减少冲突,例如非十进制数等。

HASH一般用来处理一个元素是否在一个集合内,大部分的时候二分查找+快速排序可以代替这个功能(STL中也有专门用来去重的),但在有些题目的运用上,则必须用到HASH

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
using namespace std;
typedef long long ll;
const int N=5e4+5;
ll f[N];
int T,n,z;
inline ll read()//读入优化
{
    ll X=0,w=0; char ch=0;
    while(!isdigit(ch)) {w|=ch==-;ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
int find(ll x) {//查找x在HASH表中的位置
    int y=x%N,yy=y;bool a=1;
    while(f[y]!=0 && f[y]!=x) {//若此位置已经有数并且没有找到这个数
        y=(yy*2-y+a)%N;
        a=!a;
    }
    if (f[y]==0) return y;//判断x在不在hash表
    else return -1;
}
int main() {
    T=read();
    while(T--) {//t组数据
        memset(f,0,sizeof(f));
        n=read();
        for(int i=1; i<=n; i++) {
            ll a=read();
            z=find(a);
            if (z!=-1) {//若不在HASH表中,即没有出现过
                printf("%lld ",a);//输出它
                f[z]=a;//并把它放入HASH表
            }
        }
        puts("");
    }
}

 

以上是关于[JLOI2011]不重复数字的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 2761: [JLOI2011]不重复数字 水题

[BZOJ2761][JLOI2011]不重复数字

bzoj2761: [JLOI2011]不重复数字

bzoj 2761: [JLOI2011]不重复数字

[JLOI2011]不重复数字

bzoj2761: [JLOI2011]不重复数字