P4305 [JLOI2011]不重复数字
题目描述
给出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个正整数。
输出格式:对于每组数据,输出一行,为去重后剩下的数字,数字之间用一个空格隔开。
输入输出样例
输入样例#1:
2
11
1 2 18 3 3 19 2 3 6 5 4
6
1 2 3 4 5 6
输出样例#1:
1 2 18 3 19 6 5 4
1 2 3 4 5 6
说明
对于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$了。
代码:
#include<bits/stdc++.h> #define il inline using namespace std; const int N=50005; int T,n,pos[N]; struct node{ int v,id; bool operator< (const node a)const{return v<a.v;} bool operator == (const node a)const{return v==a.v;} }a[N]; il bool cmp(const node &a,const node &b){return a.id<b.id;} il int gi(){ int a=0;char x=getchar();bool f=0; while((x<'0'||x>'9')&&x!='-')x=getchar(); if(x=='-')x=getchar(),f=1; while(x>='0'&&x<='9')a=a*10+x-48,x=getchar(); return f?-a:a; } int main(){ T=gi(); while(T--){ n=gi(); for(int i=1;i<=n;i++)a[i].v=gi(),a[i].id=i; stable_sort(a+1,a+n+1); int m=unique(a+1,a+n+1)-a-1; sort(a+1,a+m+1,cmp); for(int i=1;i<=m;i++)printf("%d ",a[i].v); printf("\n"); } return 0; }
PS:~蒟蒻写博客不易,转载请注明出处,万分感谢!~