题目描述
给出N个数,要求把其中重复的去掉,只保留第一次出现的数。
例如,给出的数为1 2 18 3 3 19 2 3 6 5 4,其中2和3有重复,去除后的结果为1 2 18 3 19 6 5 4。
输入输出格式
输入格式:输入第一行为正整数T,表示有T组数据。
接下来每组数据包括两行,第一行为正整数N,表示有N个数。第二行为要去重的N个正整数。
输出格式:对于每组数据,输出一行,为去重后剩下的数字,数字之间用一个空格隔开。
输入输出样例
说明
对于30%的数据,1 <= N <= 100,给出的数不大于100,均为非负整数;
对于50%的数据,1 <= N <= 10000,给出的数不大于10000,均为非负整数;
对于100%的数据,1 <= N <= 50000,给出的数在32位有符号整数范围内。 T≤50
Solution:
本题,额,$STL$大法好。
很多人都用了$hash$或者$map$,我这里核心就是排序和$unique$去重。
首先我们对读入的数记录大小$a[i].v$和排名$a[i].id$,先以$v$为关键字从小到大排序(注意要用稳定排序$stable-sort$,保证之后去重时相同数字只留下排名小的)。
再进行$unique$去重,对于去重后的$m$个元素,按排名从小到大排序,最后顺序输出就$OK$了。
代码:
1 #include<bits/stdc++.h> 2 #define il inline 3 using namespace std; 4 const int N=50005; 5 int T,n,pos[N]; 6 struct node{ 7 int v,id; 8 bool operator< (const node a)const{return v<a.v;} 9 bool operator == (const node a)const{return v==a.v;} 10 }a[N]; 11 il bool cmp(const node &a,const node &b){return a.id<b.id;} 12 il int gi(){ 13 int a=0;char x=getchar();bool f=0; 14 while((x<'0'||x>'9')&&x!='-')x=getchar(); 15 if(x=='-')x=getchar(),f=1; 16 while(x>='0'&&x<='9')a=a*10+x-48,x=getchar(); 17 return f?-a:a; 18 } 19 int main(){ 20 T=gi(); 21 while(T--){ 22 n=gi(); 23 for(int i=1;i<=n;i++)a[i].v=gi(),a[i].id=i; 24 stable_sort(a+1,a+n+1); 25 int m=unique(a+1,a+n+1)-a-1; 26 sort(a+1,a+m+1,cmp); 27 for(int i=1;i<=m;i++)printf("%d ",a[i].v); 28 printf("\n"); 29 } 30 return 0; 31 }