题目链接:https://vjudge.net/contest/252597#problem/C
1.超内存了,如何处理
#include<stdio.h>
#include<string>
#include<iostream>
#include<stack>
using namespace std;
typedef long long LL;
const int maxn = 300005;
stack<LL> nstack[maxn];
stack<LL> ss;
LL n, q,v,s;
int t,op;
void init()
{
for (LL i = 0; i <= n; i++)
while (!nstack[i].empty())
nstack[i].pop();
}
int main()
{
scanf("%d", &t);
while (t--)
{
init();
scanf("%lld%lld", &n, &q);
while (q--)
{
scanf("%d", &op);
if (op == 1)
{
scanf("%lld%lld", &s, &v);
nstack[s].push(v);
}
else if (op == 2)
{
scanf("%lld", &s);
if (nstack[s].size())
{
LL tmp = nstack[s].top();
nstack[s].pop();
printf("%lld\n", tmp);
}
else puts("EMPTY");
}
else
{
while (!ss.empty())ss.pop();
scanf("%lld%lld", &s, &v);
while(!nstack[v].empty())
{
ss.push(nstack[v].top());
nstack[v].pop();
}
while (!ss.empty())
{
nstack[s].push(ss.top());
ss.pop();
}
}
}
}
return 0;
}
然后实在没办法优化内存,垂死挣扎改一些LL改成int,虽然我知道肯定不行,但是还是想交一发,果然还是mle(但我知道了int是可以存10^5)
难道不能用stl自带的栈来实现?
然后我去看了看底层的实现
emmm我把原来的代码所有的改成int(int也可以包括10^9啊啊啊),报了一个从未出现的错误:段错误
网上大神说是内存超了或者是编译器的问题?
#include<string.h>
#include<stdio.h>
#include<string>
#include<iostream>
#include<stack>
using namespace std;
const int maxn = 1000005;
stack<int> nstack[maxn];
stack<int> ss;
int v, n, q, s;
int t, op;
void init()
{
for (int i = 0; i <= n; i++)
while (!nstack[i].empty()) nstack[i].pop();
}
int main()
{
scanf("%d", &t);
while (t--)
{
init();
scanf("%d%d", &n, &q);
while (q--)
{
scanf("%d", &op);
if (op == 1)
{
scanf("%d%d", &s, &v);
nstack[s].push(v);
}
else if (op == 2)
{
scanf("%d", &s);
if (nstack[s].size())
{
printf("%d\n", nstack[s].top());
nstack[s].pop();
}
else puts("EMPTY");
}
else
{
while (!ss.empty())ss.pop();
scanf("%d%d", &s, &v);
while (!nstack[v].empty())
{
ss.push(nstack[v].top());
nstack[v].pop();
}
while (!ss.empty())
{
nstack[s].push(ss.top());
ss.pop();
}
}
}
}
return 0;
}
我试了vector,仍旧mle
#include<stdio.h>
#include<string>
#include<iostream>
#include<vector>
using namespace std;
const int maxn = 1000005;
vector<int> nstack[maxn];
int n, q, s,v;
int t, op;
void init()
{
for (int i = 0; i <= n; i++)
nstack[i].clear();
}
int main()
{
scanf("%d", &t);
while (t--)
{
init();
scanf("%d%d", &n, &q);
while (q--)
{
scanf("%d", &op);
if (op == 1)
{
scanf("%d%d", &s, &v);
nstack[s].push_back(v);
}
else if (op == 2)
{
scanf("%d", &s);
if (nstack[s].size())
{
printf("%d\n", nstack[s][nstack[s].size() - 1]);
nstack[s].pop_back();
}
else puts("EMPTY");
}
else
{
scanf("%d%d", &s, &v);
nstack[s].insert(nstack[s].end(),nstack[v].begin(), nstack[v].end());
nstack[v].clear();
}
}
}
return 0;
}
那我改改list吧,过了
(有个神奇的函数叫splice)
#include<stdio.h>
#include<string>
#include<iostream>
#include<list>
using namespace std;
const int maxn = 1000005;
list<int> nstack[maxn];
int v, n, q, s;
int t, op;
void init()
{
for (int i = 0; i <= n; i++)
nstack[i].clear();
}
int main()
{
scanf("%d", &t);
while (t--)
{
init();
scanf("%d%d", &n, &q);
while (q--)
{
scanf("%d", &op);
if (op == 1)
{
scanf("%d%d", &s, &v);
nstack[s].push_back(v);
}
else if (op == 2)
{
scanf("%d", &s);
if (!nstack[s].empty())
{
printf("%d\n", nstack[s].back());
nstack[s].pop_back();
}
else puts("EMPTY");
}
else
{
scanf("%d%d", &s, &v);
nstack[s].splice(nstack[s].end(), nstack[v]);
//我试了试不用内置函数会超时
//原因是:用链表的内置函数
//直接可以把一个链表的尾连接另一个链表的头,
//而如果一个个结点弄的话肯定会超时,
//同理两个stack进行拷贝时无内置函数应该也会超时,vector也是
//list在进行插入删除有很多优势见https://www.cnblogs.com/shijingjing07/p/5587719.html
/*while (!nstack[v].empty())
{
nstack[s].push_back(nstack[v].front());
nstack[v].pop_front();
}*/
}
}
}
return 0;
}
来自大神们的解释
为什么不能用stack
对了忘了补充大牛们用数组做的方法了:把所有数字都存在一个数组a中,然后用三个数组top,bottom,next分别记录栈顶,栈底和栈顶下一个数字在数组a下标的数字