東東的舞會(dance.pas/.c/.cpp)
題目描述
東東的幼兒園舉辦舞會,一共有n個小朋友參加。
老師讓所有的小朋友站成一列,從左開始編號,最左邊的小朋友編號為1,最右邊的為n。每個小朋友跳舞的熟練度我們用乙個整數來表示,第i個小朋友的熟練度為ai,每次相鄰小朋友熟練度最接近的一對會出列跳舞,如果有多對那麼最左邊的那一對會先出列。
東東是個愛思考的孩子,他想如果出列的小朋友不再回到隊伍當中的話,那麼出列的順序是什麼樣的呢?
輸入格式
第一行是乙個正整數 n。
第二行n個由空格隔開的正整數,第i個正整數ai,表示佇列中第i個小朋友的跳舞熟練度。
輸出格式
一行,表示按順序出列的小朋友的編號。(一對小朋友編號小的在前。)
樣例輸入
5 5 3 2 1 8
樣例輸出
2 3 1 4
資料範圍與約定
對於 40% 的資料,1≤n≤1000
對於 100% 的資料,1≤n≤10000,1≤ai≤100000
看到題目第一眼就知道是堆,寫了很久,但是評測之後發現資料很水,同學的暴力列舉都能ac。
模擬賽的解題報告如下:
自己維護小根堆然後瞬間ac的**:
program mys;
var i,j,k,m,n,nn,t,tt,t1,t2:longint;
a,f,l,r,zz,yy:array[0..300000]of longint;
b:array[0..300000]of boolean;
procedure
put(x,y:longint);
var p,tt:longint;
begin
inc(t);
f[t]:=abs(a[x]-a[y]);
l[t]:=x; r[t]:=y;
tt:=t;
while (tt>1)and((f[tt]div
2])or((f[tt]=f[tt div
2])and(l[tt]div
2]))) do
begin
p:=f[tt]; f[tt]:=f[tt div
2]; f[tt div
2]:=p;
p:=l[tt]; l[tt]:=l[tt div
2]; l[tt div
2]:=p;
p:=r[tt]; r[tt]:=r[tt div
2]; r[tt div
2]:=p;
tt:=tt div
2;end;
end;
procedure
pop;
var p,tt,son:longint;
begin
f[1]:=f[t];
l[1]:=l[t];
r[1]:=r[t];
dec(t);
tt:=1;
while (tt*2
<=t) do
begin
if (tt*2+1>t) or ((f[tt*2])2+1])or((f[tt*2]=f[tt*2+1])and(l[tt*2]2+1])) then
son:=tt*2
else son:=tt*2+1;
if (f[son]or((f[tt]=f[son])and(l[son]then
begin
p:=f[tt]; f[tt]:=f[son]; f[son]:=p;
p:=l[tt]; l[tt]:=l[son]; l[son]:=p;
p:=r[tt]; r[tt]:=r[son]; r[son]:=p;
tt:=son;
endelse
break;
end;
end;
begin
assign(input,'dance.in');reset(input);
assign(output,'dance.out');rewrite(output);
readln(n);
nn:=n;
for i:=1
to n do
read(a[i]);
for i:=1
to n do
begin
zz[i]:=i-1;
yy[i]:=i+1;
end;
fillchar(b,sizeof(b),false);
for i:=1
to n-1
do put(i,i+1);
repeat
while b[l[1]]or b[r[1]] do pop;
if l[1]1] then
write(l[1],' ',r[1],' ')
else
write(r[1],' ',l[1],' ');
b[r[1]]:=true; b[l[1]]:=true;
t1:=zz[l[1]];
t2:=yy[r[1]];
zz[t2]:=t1;
yy[t1]:=t2;
n:=n-2;
pop;
if (t1>0)and(t2<=nn) then
begin
put(t1,t2);
end;
until n<2;
close(input);
close(output);
end.
堆(大根堆 小根堆)
堆又可稱之為完全二叉堆。這是乙個邏輯上基於完全二叉樹 物理上一般基於線性資料結構 如陣列 向量 鍊錶等 的一種資料結構。學習過完全二叉樹的同學們都應該了解,完全二叉樹在物理上可以用線性資料結構進行表示 或者儲存 例如陣列int a 5 就可以用來描述乙個擁有5個結點的完全二叉樹。那麼基於完全二叉樹的...
堆(Heap)大根堆 小根堆
具有以下的特點 1 完全二叉樹 2 heap中儲存的值是偏序 min heap 父節點的值小於或等於子節點的值 max heap 父節點的值大於或等於子節點的值 一般都用陣列來表示堆,i結點的父結點下標就為 i 1 2。它的左右子結點下標分別為2 i 1和2 i 2。如第0個結點左右子結點下標分別為...
堆(Heap)大根堆 小根堆
目錄一般都用陣列來表示堆,i結點的父結點下標就為 i 1 2。它的左右子結點下標分別為2 i 1和2 i 2。如第0個結點左右子結點下標分別為1和2。插入乙個元素 新元素被加入到heap的末尾,然後更新樹以恢復堆的次序。每次插入都是將新資料放在陣列最後。可以發現從這個新資料的父結點到根結點必然為乙個...