[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]不重复数字的主要内容,如果未能解决你的问题,请参考以下文章