bzoj 2761
解法很多。可用哈希、离散化、平衡树。
首先是哈希,记得要挂链。然而我并不会什么高深的哈希函数。
#include<cstdio> #include<cctype> #include<cstring> #define P 2133247 using namespace std; int abs(int x){return x<0? -x:x;} int read(){ char c; while(!isdigit(c=getchar()) && c!='-'); int x=0,y=1; if(c=='-') y=-1; else x=c-'0'; while(isdigit(c=getchar())) x=x*10+c-'0'; return x*y; } int cnt,hed[2133247],nxt[50001],val[50001]; bool find(int x){ int y=abs(x%P); for(int i=hed[y];i;i=nxt[i]) if(val[i]==x) return 1; nxt[++cnt]=hed[y]; val[hed[y]=cnt]=x; return 0; } int main(){ int t=read(); while(t--){ int n=read(),fs=0; cnt=0; memset(hed,0,sizeof hed); while(n--){ int x=read(); if(!find(x)) if(!fs) fs=1,printf("%d",x); else printf(" %d",x); } printf("\n"); } return 0; }
离散化,排序一下标号后用布尔数组判重。
#include<cstdio> #include<cctype> #include<cstring> #include<algorithm> using namespace std; int read(){ char c; while(!isdigit(c=getchar()) && c!='-'); int x=0,y=1; if(c=='-') y=-1; else x=c-'0'; while(isdigit(c=getchar())) x=x*10+c-'0'; return x*y; } struct hash{ int va,id; }b[50001]; int a[50001],c[50001]; bool yes[50001]; bool cmp(hash x,hash y){return x.va<y.va;} int main(){ int t=read(); while(t--){ int n=read(),fs=0; memset(yes,0,sizeof yes); for(int i=0;i<n;i+=1){ a[i]=c[i]=read(); b[i].va=a[i]; b[i].id=i; } sort(b,b+n,cmp); int pre=b[0].va,now=0; a[b[0].id]=0; for(int i=1;i<n;i+=1) if(pre==b[i].va) a[b[i].id]=now; else pre=b[i].va,a[b[i].id]=++now; for(int i=0;i<n;i+=1) if(!yes[a[i]]){ yes[a[i]]=1; if(fs) printf(" %d",c[i]); else fs=1,printf("%d",c[i]); } printf("\n"); } return 0; }
说是说平衡树,其实就是个set,懒得手打咯。STL大法真不错。
#include<cstdio> #include<cctype> #include<set> using namespace std; int read(){ char c; while(!isdigit(c=getchar()) && c!='-'); int x=0,y=1; if(c=='-') y=-1; else x=c-'0'; while(isdigit(c=getchar())) x=x*10+c-'0'; return x*y; } set<int> s; int main(){ int t=read(); while(t--){ int n=read(),fs=0; s.clear(); while(n--){ int x=read(); if(!s.count(x)){ if(fs==1) printf(" %d",x); else fs=1,printf("%d",x); s.insert(x); } } printf("\n"); } return 0; }