朋友在刷PTA遇到了這樣一道有意思的題:
實現起來不難,但是總是提示時間超限或內存超限。
這裏給出輸出入和輸出示例:
輸入
2
2 15
1 1 10
1 1 11
1 2 12
1 2 13
3 1 2
1 2 14
2 1
2 1
2 1
2 1
2 1
3 2 1
2 2
2 2
2 2
3 7
3 1 2
3 1 3
3 2 1
2 1
2 2
2 3
2 3
輸出:
13
12
11
10
EMPTY
14
EMPTY
EMPTY
EMPTY
EMPTY
EMPTY
EMPTY
簡單的用二維數組開闢好空間顯然是行不通的,因而選擇使用鏈表:
typedef struct stack
{
int n;
struct stack* next;
}*sta,stack;
首先我們實現第一個操作將數據存入鏈表:
void opera1(sta head,int n)
{
sta p=(sta)malloc(sizeof(stack));
p->next=head->next;
head->next=p;
p->n=n;
//printf("%d",p->n);
}
這裏直接採用了頭插法。這樣我們可以方便對棧頂進行操作。我們在實現第二種操作時就是利用這種特性:
void opera2(sta head)
{
sta p;
if(head->next==NULL)
printf("EMPTY\n");
else
{
p=head->next;
printf("%d\n",p->n);
head->next=p->next;
free(p);
}
}
接下來是方法3也是簡單的拼接操作,可以直接把鏈表拼接到頭部降低時間複雜度:
void opera3(sta head1,sta head2)
{
sta p=head1;
int i=0;
while(p->next!=NULL)
{
p=p->next;
i++;
}
if(i!=0)
{
p->next=head2->next;
head2->next=head1->next;
head1->next=NULL;
}
}
爲了降低其對空間的佔用且符合規範,由於存在多組輸入我們要及時釋放內存:
void destroy(sta head)
{
sta p=head;
sta q;
while(p!=NULL)
{
q=p->next;
free(p);
p=q;
}
}
爲了進一步節約空間我們需要將指針數組的大小也可變,也就是創建一個指針的指針來作爲數組的首地址:
sta* head=NULL;
接下來只要根據需要分配空間就可以了:
head=(sta*)malloc(sizeof(sta)*n);
n爲我們需要的頭結點數量。
main函數裏通過switch語言調用各個方法,同時爲了避免空間浪費我們只在對應標號的棧被用到時創建頭結點。
接下來我們直接給出整個main函數的代碼:
int main()
{
int t,i;
scanf("%d",&t);
for(i=0;i<t;i++)
{
int n,q,s,v,h1,h2;
int j,k;
int op;
sta* head=NULL;
scanf("%d %d",&n,&q);
head=(sta*)malloc(sizeof(sta)*n);
for(j=0;j<n;j++)
head[j]=NULL;
for(k=0;k<q;k++)
{
scanf("%d",&op);
switch(op)
{
case 1:
scanf("%d %d",&s,&v);
s--;
if(head[s]==NULL)
{
head[s]=(sta)malloc(sizeof(sta));
head[s]->next=NULL;
}
opera1(head[s],v);
break;
case 2:
scanf("%d",&s);
s--;
if(head[s]==NULL)
{
head[s]=(sta)malloc(sizeof(sta));
head[s]->next=NULL;
}
//printf("%d",head[s]->next->n);
opera2(head[s]);
break;
case 3:
scanf("%d %d",&h1,&h2);
h1--;
h2--;
if(head[h1]==NULL)
{
head[h1]=(sta)malloc(sizeof(sta));
head[h1]->next=NULL;
}
if(head[h2]==NULL)
{
head[h2]=(sta)malloc(sizeof(sta));
head[h2]->next=NULL;
}
opera3(head[h2],head[h1]);
}
}
for(k=0;k<n;k++)
{
if(head[k]!=NULL)
destroy(head[k]);
}
}
return 0;
}
接下來我們給出整體代碼:
#include<stdio.h>
#include<stdlib.h>
typedef struct stack
{
int n;
struct stack* next;
}*sta,stack;
void opera1(sta head,int n)
{
sta p=(sta)malloc(sizeof(stack));
p->next=head->next;
head->next=p;
p->n=n;
//printf("%d",p->n);
}
void opera2(sta head)
{
sta p;
if(head->next==NULL)
printf("EMPTY\n");
else
{
p=head->next;
printf("%d\n",p->n);
head->next=p->next;
free(p);
}
}
void opera3(sta head1,sta head2)
{
sta p=head1;
int i=0;
while(p->next!=NULL)
{
p=p->next;
i++;
}
if(i!=0)
{
p->next=head2->next;
head2->next=head1->next;
head1->next=NULL;
}
}
void destroy(sta head)
{
sta p=head;
sta q;
while(p!=NULL)
{
q=p->next;
free(p);
p=q;
}
}
int main()
{
int t,i;
scanf("%d",&t);
for(i=0;i<t;i++)
{
int n,q,s,v,h1,h2;
int j,k;
int op;
sta* head=NULL;
scanf("%d %d",&n,&q);
head=(sta*)malloc(sizeof(sta)*n);
for(j=0;j<n;j++)
head[j]=NULL;
for(k=0;k<q;k++)
{
scanf("%d",&op);
switch(op)
{
case 1:
scanf("%d %d",&s,&v);
s--;
if(head[s]==NULL)
{
head[s]=(sta)malloc(sizeof(sta));
head[s]->next=NULL;
}
opera1(head[s],v);
break;
case 2:
scanf("%d",&s);
s--;
if(head[s]==NULL)
{
head[s]=(sta)malloc(sizeof(sta));
head[s]->next=NULL;
}
//printf("%d",head[s]->next->n);
opera2(head[s]);
break;
case 3:
scanf("%d %d",&h1,&h2);
h1--;
h2--;
if(head[h1]==NULL)
{
head[h1]=(sta)malloc(sizeof(sta));
head[h1]->next=NULL;
}
if(head[h2]==NULL)
{
head[h2]=(sta)malloc(sizeof(sta));
head[h2]->next=NULL;
}
opera3(head[h2],head[h1]);
}
}
for(k=0;k<n;k++)
{
if(head[k]!=NULL)
destroy(head[k]);
}
}
return 0;
}