2011-04-07 13:06:09Morris
a091. 今晚打老虎
這台機器有三顆功能鍵跟數字小鍵盤
功能鈕上分別寫著
1. Insert
2. Query MAX
3. Query MIN
旁邊寫著一行粗字: 極值經查詢後將會刪除
題目看到這各位也明瞭了吧
請你寫出這台機器的程式
可以插入數字並且查詢其中的最大值與最小值
輸入說明
:
每行輸入開頭有三種情形
- 1: 插入操作,其後會跟著一數字 N 代表插入的數字 (0 ≤ N ≤ 231-1)
- 2: 查詢最大值
- 3: 查詢最小值
同一時間內最多有 100,0000 個數字
輸出說明
:
每筆查詢輸出一行
每行只有一個數字
範例輸入 :
若題目沒有特別說明,則應該以多測資的方式讀取,若不知如何讀取請參考 a001 的範例程式。
1 3
1 100
2
1 4
3
範例輸出 :
100
3
提示
:
× example編輯
出處
:
???? | ????
(管理:morris1028)
實作演算法 : Deap
估計min-max heap也行得通
功能都是在記憶體N的情況下,同時提供
Fetch max/min O(1)
Delete max/min O(lgN)
Insert O(lgN)
/**********************************************************************************/
/* Problem: a091 "今晚打老虎" from ???? | ???? */
/* Language: C */
/* Result: AC (464ms, 1048KB) on ZeroJudge */
/* Author: morris1028 at 2011-04-06 22:14:20 */
/**********************************************************************************/
#include<stdio.h>
#include<stdlib.h>
struct Deap{
int V;
}Deap[1000001], T;
int L=1;
int Judge(int p) {
while(p > 3) p/=2;
return p; /*2 left-min heap 3 right-max heap*/
}
int MinPartner(int p) {
int i=p, s=1;
while(p > 3) p/=2, s*=2;
return i-s;
}
int MaxPartner(int p) {
if(p == 2) return 2;
int i=p, s=1;
while(p > 3) p/=2, s*=2;
if(i+s > L) return (i+s)/2;
return i+s;
}
void MinInsert(int S, int N) {
int P=S/2;
while(P > 1 && Deap[P].V > N) Deap[S].V=Deap[P].V, S=P, P=S/2;
Deap[S].V=N;
}
void MaxInsert(int S, int N) {
int P=S/2;
while(P > 1 && Deap[P].V < N) Deap[S].V=Deap[P].V, S=P, P=S/2;
Deap[S].V=N;
}
void Deap_Insert(int N) {
L++;
if(L==2) {
Deap[2].V=N;
return;
}
int p=L, i;
switch( Judge(p) ) {
case 3:/*right */
i=MinPartner(p);
if(N < Deap[i].V) Deap[p].V=Deap[i].V, MinInsert(i, N);
else MaxInsert(p, N);
break;
case 2:/*left */
i=MaxPartner(p);
if(N > Deap[i].V) Deap[p].V=Deap[i].V, MaxInsert(i, N);
else MinInsert(p, N);
break;
}
}
void Delete_Max()
{
int p=L, t=Deap[L--].V, a, b, i;
for(a = 3; a*2 <= L; a = b) {
a*=2;
if(a < L && Deap[a].V < Deap[a+1].V) b=a+1;
else b=a;
Deap[a/2].V=Deap[b].V;
}
i= MinPartner(a);
int biggest=i;
if(2*i <= L) {
biggest=2*i;
if (((2*i + 1)<=L) && (Deap[2*i].V < Deap[2*i+1].V))
biggest++;
}
if(t < Deap[biggest].V) {
Deap[a].V=Deap[biggest].V;
MinInsert(biggest, t);
}
else MaxInsert(a, t);
}
void Delete_Min()
{
int p=L, t=Deap[L--].V, a, b, i;
for(a = 2; a*2<=L; a = b) {
a*=2;
if(a < L && Deap[a].V > Deap[a+1].V)
b=a+1;
else b=a;
Deap[a/2].V=Deap[b].V;
}
i= MaxPartner(a);
if(t > Deap[i].V) {
Deap[a]=Deap[i];
MaxInsert(i, t);
}
else MinInsert(a, t);
}
main() {
static int D, N, a;
while(scanf("%d",&D)==1) {
switch(D) {
case 1:scanf("%d",&N), Deap_Insert(N);break;
case 2:printf("%d\n", (L==2) ? Deap[2].V : Deap[3].V );
if(L==2) Delete_Min();
else Delete_Max();break;
case 3:printf("%d\n", Deap[2].V), Delete_Min();break;
}
}
return 0;
}
實作演算法 : Deap
估計min-max heap也行得通
功能都是在記憶體N的情況下,同時提供
Fetch max/min O(1)
Delete max/min O(lgN)
Insert O(lgN)
/**********************************************************************************/
/* Problem: a091 "今晚打老虎" from ???? | ???? */
/* Language: C */
/* Result: AC (464ms, 1048KB) on ZeroJudge */
/* Author: morris1028 at 2011-04-06 22:14:20 */
/**********************************************************************************/
#include<stdio.h>
#include<stdlib.h>
struct Deap{
int V;
}Deap[1000001], T;
int L=1;
int Judge(int p) {
while(p > 3) p/=2;
return p; /*2 left-min heap 3 right-max heap*/
}
int MinPartner(int p) {
int i=p, s=1;
while(p > 3) p/=2, s*=2;
return i-s;
}
int MaxPartner(int p) {
if(p == 2) return 2;
int i=p, s=1;
while(p > 3) p/=2, s*=2;
if(i+s > L) return (i+s)/2;
return i+s;
}
void MinInsert(int S, int N) {
int P=S/2;
while(P > 1 && Deap[P].V > N) Deap[S].V=Deap[P].V, S=P, P=S/2;
Deap[S].V=N;
}
void MaxInsert(int S, int N) {
int P=S/2;
while(P > 1 && Deap[P].V < N) Deap[S].V=Deap[P].V, S=P, P=S/2;
Deap[S].V=N;
}
void Deap_Insert(int N) {
L++;
if(L==2) {
Deap[2].V=N;
return;
}
int p=L, i;
switch( Judge(p) ) {
case 3:/*right */
i=MinPartner(p);
if(N < Deap[i].V) Deap[p].V=Deap[i].V, MinInsert(i, N);
else MaxInsert(p, N);
break;
case 2:/*left */
i=MaxPartner(p);
if(N > Deap[i].V) Deap[p].V=Deap[i].V, MaxInsert(i, N);
else MinInsert(p, N);
break;
}
}
void Delete_Max()
{
int p=L, t=Deap[L--].V, a, b, i;
for(a = 3; a*2 <= L; a = b) {
a*=2;
if(a < L && Deap[a].V < Deap[a+1].V) b=a+1;
else b=a;
Deap[a/2].V=Deap[b].V;
}
i= MinPartner(a);
int biggest=i;
if(2*i <= L) {
biggest=2*i;
if (((2*i + 1)<=L) && (Deap[2*i].V < Deap[2*i+1].V))
biggest++;
}
if(t < Deap[biggest].V) {
Deap[a].V=Deap[biggest].V;
MinInsert(biggest, t);
}
else MaxInsert(a, t);
}
void Delete_Min()
{
int p=L, t=Deap[L--].V, a, b, i;
for(a = 2; a*2<=L; a = b) {
a*=2;
if(a < L && Deap[a].V > Deap[a+1].V)
b=a+1;
else b=a;
Deap[a/2].V=Deap[b].V;
}
i= MaxPartner(a);
if(t > Deap[i].V) {
Deap[a]=Deap[i];
MaxInsert(i, t);
}
else MinInsert(a, t);
}
main() {
static int D, N, a;
while(scanf("%d",&D)==1) {
switch(D) {
case 1:scanf("%d",&N), Deap_Insert(N);break;
case 2:printf("%d\n", (L==2) ? Deap[2].V : Deap[3].V );
if(L==2) Delete_Min();
else Delete_Max();break;
case 3:printf("%d\n", Deap[2].V), Delete_Min();break;
}
}
return 0;
}
上一篇:a004. 文文的求婚
下一篇:d539. 區間 MAX