[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个正整数。

输出格式:

对于每组数据,输出一行,为去重后剩下的数字,数字之间用一个空格隔开。

输入输出样例

输入

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;
}

猜你喜欢

转载自blog.csdn.net/zsyzClb/article/details/84166598
今日推荐