[JLOI2011]不重複數字
阿新 • • 發佈:2018-11-25
題目描述
給出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; }