1. 程式人生 > >[JLOI2011]不重複數字

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