有一个黑箱子,里面会按升序存储整数,你可以对黑箱子下达下面的指令:
a. ADD n 将n加入黑箱子
b. Get 获得一个数,这个数在黑箱子里的序号(从0开始计数)是Get的出现次数。
黑箱子中最初存了一个数0,现给你一个操作序列,要你输出Get命令时获的那个数。
输入:
每行是一个命令,假如命令是”ADD”,则后面空一格,有一个整数。输入时保证GET命令不会越界
输出:
每行输出一个整数,整数为对应Get获得值。
a. ADD n 将n加入黑箱子
b. Get 获得一个数,这个数在黑箱子里的序号(从0开始计数)是Get的出现次数。
黑箱子中最初存了一个数0,现给你一个操作序列,要你输出Get命令时获的那个数。
输入:
每行是一个命令,假如命令是”ADD”,则后面空一格,有一个整数。输入时保证GET命令不会越界
输出:
每行输出一个整数,整数为对应Get获得值。
Sample Input
ADD 3
GET
ADD 1
GET
ADD -4
ADD 2
ADD 8
GET
GET
ADD -1000
ADD 2
GET
Sample Output
3
3
2
3
2
//Time limit Exceed
#include <stdio.h>
#include <stdlib.h>
#define N 1000000
int MinHeap[N],minsize;
int MaxHeap[N],maxsize=1;
int minHeapPop()
{
//用temp保存被弹出的元素,val保存最后一个待调整元素,h找到val应放置的位置,child为孩子位置
int temp=MinHeap[1],val,h,child;
val=MinHeap[minsize--];
for(h=1,child=2*h; child<=minsize&&(val>MinHeap[child]||val>MinHeap[child+1]) ;){
if(MinHeap[child+1]<MinHeap[child]){
child++;
}
MinHeap[h]=MinHeap[child];
h=child,child=2*h;
}
MinHeap[h]=val;
return temp;
}
int maxHeapPop()
{
int temp=MaxHeap[1],val,h,child;
val=MaxHeap[maxsize--];
for(h=1,child=2*h; child<=maxsize&&(val<MaxHeap[child]||val<MaxHeap[child+1]) ;){
if(MaxHeap[child+1]>MaxHeap[child]){
child++;
}
MaxHeap[h]=MaxHeap[child];
h=child,child=2*h;
}
MaxHeap[h]=val;
return temp;
}
void minHeapInsert(int x)
{
int h=++minsize,parent=h/2;
while(h>1 && x<MinHeap[parent]){
MinHeap[h]=MinHeap[parent];
h=parent,parent=h/2;
}
MinHeap[h]=x;
}
void maxHeapInsert(int x)
{
int h=++maxsize,parent=h/2;
while(h>1 && x>MaxHeap[parent]){
MaxHeap[h]=MaxHeap[parent];
h=parent,parent=h/2;
}
MaxHeap[h]=x;
}
void blackBoxOpera()
{
char cmd[5];
int x;
while(scanf("%s",cmd)){
if(cmd[0]=="G"){//the MinHeap"s top element always is the answer
printf("%d\n",MinHeap[1]);
maxHeapInsert(minHeapPop());
}
else{
scanf("%d",&x);
if(x<MaxHeap[1]){//the MaxHeap"s top is next "GET" position
minHeapInsert(maxHeapPop());
maxHeapInsert(x);
}
else
minHeapInsert(x);
}//else
}//while
}
int main()
{
blackBoxOpera();
return 0;
}
最开始用双向链表做的,以为可以。果断超时。花了些时间搞这个堆,还是不行吖?
解决方案
10
那就试试Splay Tree
5
不知道B树,行不?
25
B树可以吗?你可以试试吧,下面的代码可以参考下。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/* Balance flag */
#define RH 1
#define LH -1
#define BH 0
static int lev_m=0;
typedef struct avlNode{
int data;
int balance;
int level;
struct avlNode *right;
struct avlNode *left;
}*PavlNode;
void lltree(PavlNode *node)
{
PavlNode lnode;
lnode = (*node)->left;
(*node)->left = lnode->right;
lnode->right = *node;
*node=lnode;
}
void lrtree(PavlNode *node)
{
PavlNode rnode,lnode;
lnode = (*node)->left;
rnode = lnode->right;
(*node)->left = rnode;
lnode->right = rnode->left;
rnode -> left = lnode;
lltree(node);
}
void left_balance_tree(PavlNode *node)
{
PavlNode rnode,lnode;
lnode = (*node)->left;
switch(lnode->balance){
case LH:
(*node)->balance = lnode->balance = BH;
lltree(node);
break;
case RH:
rnode = lnode->right;
switch(rnode->balance){
case BH:
(*node)->balance = BH;
lnode->balance = BH;
break;
case LH:
(*node)->balance = RH;
lnode->balance = BH;
break;
case RH:
(*node)->balance = BH;
lnode->balance = LH;
break;
}
rnode->balance = BH;
lrtree(node);
break;
defult:
// do nothing
break;
}
}
void rrtree(PavlNode *node)
{
PavlNode rnode;
rnode = (*node)->right;
(*node)->right = rnode->left;
rnode->left = *node;
*node=rnode;
}
void rltree(PavlNode *node)
{
PavlNode rnode,lnode;
rnode = (*node)->right;
lnode = rnode->left;
(*node)->right = rnode->left;
rnode->left = lnode->right;
lnode -> right = rnode;
rrtree(node);
}
void right_balance_tree(PavlNode *node)
{
PavlNode rnode,lnode;
rnode = (*node)->right;
switch(rnode->balance){
case LH:
lnode = rnode->left;
switch(lnode->balance){
case BH:
(*node)->balance = BH;
rnode->balance = BH;
break;
case LH:
(*node)->balance = LH;
rnode->balance = BH;
break;
case RH:
(*node)->balance = BH;
rnode->balance = RH;
break;
defult:
break;
}
lnode->balance = BH;
rltree(node);
break;
case RH:
(*node)->balance = rnode->balance = BH;
rrtree(node);
break;
default:
break;
}
}
int create_tree(PavlNode *node, int data, int* taller){
if((*node) == NULL){
(*node) = malloc(sizeof(struct avlNode));
(*node)->data = data;
(*node)->balance = BH;
(*node)->level = 0;
(*node)->right = NULL;
(*node)->left = NULL;
return 1;
}
if( data <= (*node)->data ){
if(!create_tree(&((*node)->left),data,taller)){
return 0;
}
if(*taller){
switch((*node)->balance){
case BH:
(*node)->balance = LH;
*taller = 1;
break;
case LH:
left_balance_tree(node);
*taller = 0;
break;
case RH:
(*node)->balance = BH;
*taller = 0;
break;
default:
// do nothing
break;
}
}
}else{
if(!create_tree(&((*node)->right),data,taller)){
return 0;
}
if(*taller){
switch((*node)->balance){
case BH:
(*node)->balance = RH;
*taller = 1;
break;
case LH:
(*node)->balance = BH;
*taller = 0;
break;
case RH:
right_balance_tree(node);
*taller = 0;
break;
default:
// do nothing
break;
}
}
}
return 1;
}
void delete_tree(PavlNode* node){
if((*node) == NULL){
return;
}
if((*node)->right != NULL ){
delete_tree(&((*node)->right));
}
if((*node)->left !=NULL ){
delete_tree(&((*node)->left));
}
if(((*node)->right == NULL) && ((*node)->right == NULL)){
free((*node));
(*node) == NULL;
}
return;
}
int main(void)
{
int tmp;
int i,j;
int taller;
int lev_tmp=0;
PavlNode root=NULL;
srand((unsigned)time(NULL));
for(i=0; i<50; i++){
taller=1;
tmp = rand()%100;
create_tree(&root,tmp,&taller);
}
delete_tree(&root);
return 0;
}