题目链接
题解:
题目就不复制了,ZOJ 的题目比较难复制。
这道题题意很简单:
就是给你n个栈,q次操作。一共由三种操作
1,Push(num1,num2) 向栈num1中加入num2
2, Pop(num1) 去出栈num1中最后的元素,并输出。如果为空输出"EMPTY"
3, Link(num1,num2) 将栈2中的元素插入栈1,顺序仍然为num2的顺序。
我的想法就是用别的算法非常容易炸,因为如果有 10的五次方操作数的话,肯定会有数据翻来翻去的情况,如果不用一些高级一些的算法恐怕会T掉(嗯,这点存疑,因为我的朋友用一个O(n)的操作过了,而且据学长说用数组可能也能过)。于是我用了链表,然而链表中并没有可以用来拼接的函数,(同学发现一个splice,拼接过了可是这个是O(n)的啊,补充:不不不,只有使用了size()的操作后才会时O(n)的,直接拼接是O(1)的)我就自己开始了作死之旅,我编了一个链表,然而一直Segmentation Fault这是我第一次看到的错误,我被他搞得头都炸裂了,一直都不知道是哪里错了交了45次。这里附上错误代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef struct Node * List;
struct Node{
int Data;
List Next;
Node(int Data = 0,List Next = NULL):Data(Data),Next(Next){}
};
List CreatList(){
List T = (List)malloc(sizeof(struct Node));
T->Next = NULL;
T->Data = 0;
return T;
}
int NuEm[100007];
List Head[100007] = {NULL};
List Tail[100007] = {NULL};
void Push(int num1,int X){
List T = (List)malloc(sizeof(struct Node));
T->Data = X;
T->Next = Head[num1]->Next;
Head[num1]->Next = T;
if (NuEm[num1] == 0)Tail[num1]->Next = Head[num1]->Next;
NuEm[num1] ++;
return ;
}
void Pop(int num){
if (NuEm[num]){
List T = Head[num]->Next;
List P = T->Next;
Head[num]->Next = P;
cout << T->Data << endl;
free(T);
NuEm[num] --;
if(NuEm[num] == 0)Tail[num]->Next = NULL;
}else {
cout << "EMPTY" << endl;
}
return ;
}
void Link(int num1,int num2){
if (NuEm[num2] == 0)
return ;
List TT = CreatList();
TT = Tail[num2];
TT->Next->Next = Head[num1]->Next;
Tail[num2]->Next = NULL;
List T = CreatList();
T->Next = Head[num2]->Next;
Head[num1] = T;
Head[num2]->Next = NULL;
NuEm[num1] += NuEm[num2];
NuEm[num2] = 0;
return ;
}
void Show(int num1){
List T = Head[num1];
while (T->Next != NULL){
T = T->Next;
cout << T->Data << endl;
}
return ;
}
int main()
{
ios::sync_with_stdio(false);
int T;
cin >> T;
while (T --){
int n,q,op,num1,num2;
cin >> n >> q;
for (int i = 1;i <= n;i ++){
Head[i] = CreatList();
Tail[i] = CreatList();
}
memset(NuEm,0,sizeof(NuEm));
while (q --){
cin >> op;
switch (op){
case 1:
cin >> num1 >> num2;
Push(num1,num2);
break;
case 2:
cin >> num1;
Pop(num1);
break;
case 3:
cin >> num1 >> num2;
Link(num1,num2);
break;
}
//Show(num1);
}
}
}
使用list的操作方法
我做这题起码学会了两个
1. STL还是得学精。
2. STL不行的时候只能靠自己数据结构的基本功,这个一定要扎实。
3.
segmentation fault的了解
我使用了STL中的list容器,交了几发终于过了,说一下感受。这种大数据还是得用scanf和printf又一次的T在了cin,cout上。
AC代码:
#include <bits/stdc++.h>
using namespace std;
list<int> li[1000007];
int main()
{
//ios::sync_with_stdio(false);
int T;
scanf("%d",&T);
//cin >> T;
while (T --){
int n,q,op,num1,num2;
//cin >> n >> q;
scanf("%d %d",&n,&q);
for (int i = 1;i <= n;i ++) li[i].clear();
while (q --){
//cin >> op;
scanf("%d",&op);
switch (op){
case 1:
//cin >> num1 >> num2;
scanf("%d %d",&num1,&num2);
li[num1].push_back(num2);
break;
case 2:
scanf("%d",&num1);
//cin >> num1;
if (li[num1].empty()) printf("EMPTY\n");//cout << "EMPTY" << endl;
else {
//cout << li[num1].back() << endl;
printf("%d\n",li[num1].back());
li[num1].pop_back();
}
break;
case 3:
scanf("%d %d",&num1,&num2);
//cin >> num1 >> num2;
li[num1].splice(li[num1].end(),li[num2]);
break;
}
}
}
}
好吧经过了又一轮的拼搏,总算是不 SF ,也不会 TLE 了,但是!!!又WA了
哎,下次再来
#include <bits/stdc++.h>
using namespace std;
typedef struct ListNode{
int Data;
ListNode* Next;
}Node ,*PNode,*Position;
PNode Head [300007];
PNode Tail [300007];
int NuEm [300007];
inline PNode CreatList(){
PNode PHead = (PNode)malloc(sizeof(Node));
PHead->Next = NULL;
return PHead;
}
void Push(int num1,int num2){
PNode PNew = (PNode)malloc(sizeof(Node));
PNew->Data = num2;
Position P = Head[num1]->Next;
PNew->Next = P;
Head[num1]->Next = PNew;
if (P == NULL)Tail[num1]->Next = PNew;
NuEm[num1]++;
return;
}
void Pop(int num1){
Position P = Head[num1]->Next;
if (P == NULL){
printf("EMPTY\n"); //cout << "EMPTY" << endl;
return ;
}
Position T = P->Next;
Head[num1]->Next = T;
printf("%d\n",P->Data);
//cout << P->Data << endl;
free(P);
if (T == NULL) Tail[num1]->Next = NULL;
NuEm[num1]--;
return;
}
void Link(int num1,int num2){
Position P = Head[num1]->Next;
if (Tail[num2]->Next == NULL)return ;
Tail[num2]->Next->Next = P;
Tail[num2]->Next = NULL;
Head[num1]->Next = Head[num2]->Next;
Head[num2] = CreatList();
NuEm[num1]++;
return;
}
void Clear (int num1){
Position P = Head[num1]->Next;
Tail[num1]->Next = NULL;
if (P == NULL)return;
Position T = P->Next;
while (T != NULL){
free(P);
P = T;
T = T->Next;
}
free(P);
Head[num1]->Next = NULL;
}
int main()
{
int T;
scanf("%d",&T);//cin >> T;
while (T --){
int N,Q,op,num1,num2;
scanf("%d %d",&N,&Q);
for (int i = 0;i <= N;i ++){
Head[i] = CreatList();
Tail[i] = CreatList();
}
while (Q --){
scanf("%d",&op); //cin >> op;
if (op == 1){
scanf("%d %d",&num1,&num2); //cin >> num1 >> num2;
Push(num1,num2);
}else if (op == 2){
scanf("%d",&num1); // cin >> num1;
Pop(num1);
printf("EMPTY\n");
}else {
scanf("%d %d",&num1,&num2); //cin >> num1 >> num2;
Link(num1,num2);
}
}
}
}