24h購物| | PChome| 登入
2011-04-07 13:06:09| 人氣2,764| 回應0 | 上一篇 | 下一篇

a091. 今晚打老虎

推薦 0 收藏 0 轉貼0 訂閱站台

內容 :

這台機器有三顆功能鍵跟數字小鍵盤

功能鈕上分別寫著

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

台長: Morris
人氣(2,764) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 心情日記(隨筆、日記、心情手札) | 個人分類: ZeroJudge |
此分類下一篇:d539. 區間 MAX
此分類上一篇:a004. 文文的求婚

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文