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$了。

代码:

 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 }

猜你喜欢

转载自www.cnblogs.com/five20/p/9032793.html