1. 程式人生 > 其它 >HDUOJ----4006The kth great number(最小堆...)

HDUOJ----4006The kth great number(最小堆...)

The kth great number

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 6020    Accepted Submission(s): 2436

Problem Description

Xiao Ming and Xiao Bao are playing a simple Numbers game. In a round Xiao Ming can choose to write down a number, or ask Xiao Bao what the kth great number is. Because the number written by Xiao Ming is too much, Xiao Bao is feeling giddy. Now, try to help Xiao Bao.

Input

There are several test cases. For each test case, the first line of input contains two positive integer n, k. Then n lines follow. If Xiao Ming choose to write down a number, there will be an " I" followed by a number that Xiao Ming will write down. If Xiao Ming choose to ask Xiao Bao, there will be a "Q", then you need to output the kth great number.

Output

The output consists of one integer representing the largest number of islands that all lie on one line.

Sample Input

8 3 I 1 I 2 I 3 Q I 5 Q I 4 Q

Sample Output

1 2 3

Hint

Xiao Ming won't ask Xiao Bao the kth great number when the number of the written number is smaller than k. (1=<k<=n<=1000000).

 題意: 大致是輸入一些數,這個過程中不斷詢問第k大的數是多少?

因而普通的排序是不行的,所以很好定義為最小堆,最大堆的求解...

但是對堆的求解也有兩種,第一種是構造一個k堆,然後再輸入資料,不斷更新維護這個k堆,我們暫時叫他第k堆吧...

這樣的話,一此題給的sample  data  為列,

所以  紅黑樹來表示的話就是下面這個了...

為了這,STL  multiset....

程式碼:

 1 #include<iostream>
 2 #include<set>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     int n,k,i,temp;
 8     char ss[2];
 9     multiset<int> sta;
10     while(scanf("%d%d",&n,&k)!=EOF)
11     {
12         sta.clear();
13         for(i=0;i<n;i++)
14         {
15             scanf("%s",ss);
16             if(*ss=='I')
17             {
18                scanf("%d",&temp);
19                if(i<k) sta.insert(temp);
20                else
21                {
22                    int head=*sta.begin();
23                    if(temp>head)
24                    {
25                      sta.erase(sta.begin());
26                      sta.insert(temp);
27                    }
28                }
29             }
30             else cout<<*(sta.begin())<<endl;
31         }
32     }
33     return 0;
34 }

方法二:

採取傳統的最小堆,最大堆求解..

 1 /*最小堆hdu 4006*/
 2 /*@code Gxjun*/
 3 #include<stdio.h>
 4 #include<string.h>
 5 #define maxn 1000002
 6 int heap[maxn],n,k;
 7 void change(int *a ,int *b){
 8     *a^=*b , *b^=*a, *a^=*b;
 9 }
10 void updata_heap(int tol)
11 {
12      if(!(tol&1))  //是偶數數表示完全二叉樹
13     {
14         if(heap[tol]<heap[tol>>1])
15            change(&heap[tol],&heap[tol>>1]);
16          tol--;  
17     }
18     for(int i=tol ; i>1 ;i-=2)
19     {
20         if(heap[i]>heap[i-1])
21         {
22             if(heap[i-1]<heap[i>>1])
23                 change(&heap[i-1],&heap[i>>1]);
24         }
25         else
26             if(heap[i]<heap[i>>1])
27                 change(&heap[i],&heap[i>>1]);
28     }
29 }
30 
31 //資料更新
32 void input_heap()
33 {
34     char ss[2];
35     int i,temp;
36     for(i=1 ; i<=k ;i++)
37       scanf("%s %d",ss,&heap[i]);
38       updata_heap(k);
39 
40     for(i=k+1 ;i<=n ;i++)
41     {
42       scanf("%s",ss);
43         if(*ss=='I')
44         {
45           scanf("%d",&temp);
46             if(temp>heap[1])
47             {
48                 heap[1]=temp;
49                 updata_heap(k);
50             }
51         }
52     else 
53         if(*ss=='Q')
54             printf("%dn",heap[1]);
55     }
56 }
57 int main()
58 {
59     /*freopen("test.out","w",stdout);*/
60     while(scanf("%d%d",&n,&k)!=EOF)
61     {
62         /*memset(heap,0,sizeof(int)*(k+2));*/
63         input_heap();
64     }
65     return 0;
66 }