题目描述
给出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个正整数。
输出格式:
对于每组数据,输出一行,为去重后剩下的数字,数字之间用一个空格隔开。
输入输出样例
输入
2 11 1 2 18 3 3 19 2 3 6 5 4 6 1 2 3 4 5 6
输出
1 2 18 3 19 6 5 4 1 2 3 4 5 6
这一道题的难点就是要保留第一位
也就是说排序去重以后要把位置还原
这与离散化有着异曲同工之妙啊!!!!
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
inline int read(){
int x=0,f=0;char s=getchar();
while(!isdigit(s))f|=s=='-',s=getchar();
while( isdigit(s))x=(x<<1)+(x<<3)+s-48,s=getchar();
return f==0?x:-x;
}
const int N=5e4+10;
int n;
struct node{
int x,pos;//x表示值,pos表示在原数组中的位置
inline bool operator<(const node &k)const{
if(x!=k.x)return x<k.x; //如果不相同,就按照值从小到大排
return pos<k.pos;//不然就按照位置排,因为只要保留第一个嘛
}
}a[N];int b[N];//b表示去重后位置还原
bool bk[N];//因为去重以后位置会有空缺,所以要判断这个位置是否有数(多组数据)
int main(){
int t=read();
while(t--){
n=read();
for(int i=1;i<=n;i++)a[i].x=read(),a[i].pos=i;
sort(a+1,a+n+1);
memset(bk,0,sizeof(bk));
b[a[1].pos]=a[1].x;bk[a[1].pos]=1;//先记录第一个
for(int i=2;i<=n;i++)//找第一个出现的数
if(a[i].x!=a[i-1].x)
b[a[i].pos]=a[i].x,bk[a[i].pos]=1;
for(int i=1;i<=n;i++)//输出
if(bk[i]) printf("%d ",b[i]);
putchar('\n');
}
return 0;
}