本题较为简单。算法很多,下面给出两种算法。
一、hash。注意负数。我的程序中没有用链表,可能会被极少一部分数据卡,但是只要rp不要太差AC还是较妥的。
代码:
const
mo=211003;
var
h:array[0..mo,0..30] of longint;
p:array[0..mo] of longint;
i,t,x,n,kk:longint;
function hash(x:longint):boolean;
var
u,num,i:longint;
begin
u:=(x mod mo+mo) mod mo;
for i:=1 to p[u] do
if h[u,i]=x then exit(false);
exit(true);
end;
procedure add(x:longint);
var
u:longint;
begin
u:=(x mod mo+mo) mod mo;
p[u]:=p[u]+1;
h[u,p[u]]:=x;
end;
begin
read(t);
while t>0 do
begin
for i:=0 to mo do p[i]:=0;
t:=t-1;
read(n); kk:=0;
for i:=1 to n do
begin
read(x);
if hash(x) then
begin
add(x);
if kk=0 then kk:=1 else write(' ');
write(x);
end;
end;
writeln;
end;
end.
二、快排。用普通的快速排序去重,注意保留初始标号,再按照原来的顺序还原结果。
AC代码:
var
tt,n,i,k:longint;
p:array[0..100000] of boolean;
a,ans,c:array[0..100000] of longint;
procedure swap(var aa,bb:longint);
var
tt:longint;
begin
tt:=aa; aa:=bb; bb:=tt;
end;
procedure qsort(r,l:longint);
var
i,j,mid,t,num:longint;
begin
i:=r; j:=l;
mid:=a[(i+j)>>1];
num:=c[(i+j)>>1];
repeat
while (a[i]<mid) or (a[i]=mid) and (c[i]<num) do i:=i+1;
while (a[j]>mid) or (a[j]=mid) and (c[j]>num) do j:=j-1;
if i<=j then
begin
swap(a[i],a[j]); swap(c[i],c[j]);
i:=i+1; j:=j-1;
end;
until i>j;
if i<l then qsort(i,l);
if r<j then qsort(r,j);
end;
begin
read(tt);
while tt>0 do begin tt:=tt-1;
read(n);
for i:=1 to n do
begin
read(a[i]); c[i]:=i;
end;
qsort(1,n);
i:=1; k:=0;
while i<=n do
begin
ans[c[i]]:=a[i]; p[c[i]]:=true;
while a[i]=a[i+1] do i:=i+1;
i:=i+1;
end;
for i:=1 to n do
if p[i] then
begin
p[i]:=false;
if k=1 then write(' ') else k:=1;
write(ans[i]);
end;
writeln;
end;
end.
P.S:注意输出!行末不要有空格!
2015.2.8
by lych