[JLOI2011]不重復數字
阿新 • • 發佈:2019-02-19
std ons pac string 是否 ash 優化 ring 例如
原題鏈接 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]不重復數字