Data Manager is a sophisticated data structure, which manages a set of data and fulfills operations on the data set. There are 3 kinds of operations:
- add n,which means adding integer n to the data set;
- delete, which means deleting the smallest integer from the data set. If the data set is empty, ignore this operation. If there are more than one smallest integers, only delete one of them.
- query, which means printing the smallest integer in the data set. If the data set is empty, ignore this operation.
Given a list of operations, you are to predict the output of the Data Manager. At the beginning, the Data Manager is empty.
Input
There is only one test case. In the first line, an integer T (T <= 500000) will be given, which is the number of operations. The next T lines contains T operations.
Output
Give output of the Data Manager, one query per line.
Sample Input
10
add 1
add 100
add -1
query
delete
query
add 2046
query
delete
query
Sample Output
-1
1
1
100
原本以为这题很简单结果写了两份代码都超时了。
超时代码1,用快排把每次输入的数从大到小进行排序,最小的即为数组的第一个元素。
删除最小元素,用伪删除将最小元素标记为一个很大的数。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define Size 500000+2
#define Max 0x7FFFFFFF
int *data = NULL;
char *Table[] = { "add", "query", "delete" };
char buffer[20] = { 0 };
int cmp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
int ReturnNum(char *str)
{
char temp[20] = { 0 };
int j, i = strchr(str, ' ') - str;
i++, j = 0;
for (; i < strlen(str); i++)
{
temp[j++] = str[i];
}
temp[j] = '\0';
return atoi(temp);
}
int FindMin(int *Source, int n, int* m)
{
int i, min = Max;
for (i = 0; i < n; i++)
{
if (min>Source[i])
{
min = Source[i];
*m = i;
}
}
return min;
}
int main()
{
data = (int *)malloc(sizeof(int)*Size);
memset(data, 0, sizeof(int)*Size);
int i,m,j = 0;
scanf("%d\n", &m);
while (m--)
{
memset(buffer, 0, sizeof(buffer));
gets(buffer);
for (i = 0; i < 3; i++)
{
if (strstr(buffer, Table[i]))
{
switch (i)
{
case 0:
data[j++] = ReturnNum(buffer);
break;
case 1:
qsort(data, j, sizeof(data[0]), cmp);
printf("%d\n", data[0]);
break;
case 2:
data[0] = Max;
break;
}
}
}
}
return 0;
}
超时代码2:不用快排,直接找到数组中的最小元素,删除方法同上。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define Size 500000+2
#define Max 0x7FFFFFFF
int data[Size] = { 0 };
char *Table[] = { "add", "query", "delete" };
char buffer[20];
int ReturnNum(char *str)
{
char temp[20] = { 0 };
int j,i = strchr(str, ' ')-str;
i++,j=0;
for (; i < strlen(str); i++)
{
temp[j++] = str[i];
}
temp[j] = '\0';
return atoi(temp);
}
int FindMin(int *Source,int n,int* m)
{
int i,min=Max;
for (i = 0; i < n; i++)
{
if (min>Source[i])
{
min = Source[i];
*m = i;
}
}
return min;
}
int IsEmpty(int *data,int n)
{
int i,flag=1;
for (i = 0; i < n; i++)
{
if (data[i])
{
flag = 0;
break;
}
}
return flag;
}
int main()
{
int i,m,p,temp,j = 0;
scanf("%d\n", &m);
while (m--)
{
gets(buffer);
for (i = 0; i < 3; i++)
{
temp = FindMin(data, j, &p);
if (strstr(buffer, Table[i]))
{
switch (i)
{
case 0:
data[j++]=ReturnNum(buffer);
break;
case 1:
if (temp!=Max)
printf("%d\n", temp);
else
printf("%d\n", 0);
break;
case 2:
if (IsEmpty(data, j))
break;
else
data[p] = Max;
break;
}
}
}
}
return 0;
}
代码3:用优先队列,每次插入一个元素,比较队列中的元素的权值,将最小的权值的元素置为头结点。
然后使整个链表从头到尾Priority值依次增加(其实没必要定义一个Priority的)
删除就很简单了,只需删除头结点即可。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define DataType int
char buffer[20];
char *Table[] = { "add", "query", "delete" };
typedef struct Queue
{
DataType data;
int Priroity;
struct Queue *pNext;
}Queue, *Que;
Que CreateNode(DataType data, int Pri)
{
Que NewNode = (Que)malloc(sizeof(Queue));
NewNode->data = data;
NewNode->Priroity = Pri;
NewNode->pNext = NULL;
return NewNode;
}
void InsertEnQueue(Que *Qhead, DataType data, int Pri)
{
Que NewNode = CreateNode(data, Pri);
if (*Qhead == NULL)
{
*Qhead = NewNode;
}
else
{
if (NewNode->Priroity < (*Qhead)->Priroity)
{
Que temp = *Qhead;
*Qhead = NewNode;
(*Qhead)->pNext = temp;
}
else
{
Que p = *Qhead;;
while (p->pNext != NULL)
{
p = p->pNext;
}
if (NewNode->Priroity >= p->Priroity)
{
p->pNext = NewNode;
}
else
{
Que p1, p2;
p1 = p2 = NULL;
p1 = *Qhead;
while (p1->pNext != NULL)
{
p2 = p1->pNext;
if (p1->Priroity <= NewNode->Priroity && p2->Priroity >= NewNode->Priroity)
{
p1->pNext = NewNode;
NewNode->pNext = p2;
break;
}
p1 = p1->pNext;
}
}
}
}
}
void DeQueue(Que *Qhead)
{
if (*Qhead == NULL)
{
return;
}
else
{
Que p = *Qhead;
*Qhead = p->pNext;
free(p);
}
}
int ReturnNum(char *str)
{
char temp[20] = { 0 };
int j, i = strchr(str, ' ') - str;
i++, j = 0;
for (; i < strlen(str); i++)
{
temp[j++] = str[i];
}
temp[j] = '\0';
return atoi(temp);
}
int main()
{
Que Head = NULL;
int i, m, temp;
scanf("%d\n", &m);
while (m--)
{
fgets(buffer, sizeof(buffer), stdin);
for (i = 0; i < 3; i++)
{
if (strstr(buffer, Table[i]))
{
switch (i)
{
case 0:
temp = ReturnNum(buffer);
InsertEnQueue(&Head, temp, temp);
break;
case 1:
if (Head == NULL)
break;
else
printf("%d\n", Head->data);
break;
case 2:
DeQueue(&Head);
break;
}
}
}
}
return 0;
}
C语言没有像C++那样强大的STL(标准模板库),或许这道题用C++的方法会简单些。可惜撸主不才,不会C++
只能这么写了。