PAT 天梯赛 L2-002 链表去重

时间:2021-09-30 20:56:10

模拟单链表的增删操作

题目链接:https://www.patest.cn/contests/gplt/L2-002

题解

最开始我脑抽用map模拟单链表进行操作,因为这样可以节约空间,并且用了cincout进行输入输出,后来发现有些样例超时了。考虑到cincout在面对大量数据的时候会很慢,所以我就换成了scanfprintf进行输入输出,果然过的样例多了,但是还是不能通过全部样例。最后换成数组模拟单链表的操作,用空间换时间,最终AC

代码如下:

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100000+10;
struct Node{
int nextad;
int key;
}nod[maxn];
int start_ad, n;
bool vis[10010]; void _output(int p) {
while(p != -1) {
printf("%05d %d ", p, nod[p].key);
if(-1 == nod[p].nextad) {
printf("-1\n");
}else {
printf("%05d\n", nod[p].nextad);
}
p = nod[p].nextad;
}
} int main() {
while(~scanf("%d%d", &start_ad, &n)) {
memset(vis, 0, sizeof(vis));
for(int i = 0; i < n; i++) {
int p,q,r;
scanf("%d%d%d", &p, &q, &r);
nod[p].key = q;
nod[p].nextad = r;
}
int pre = start_ad, next = start_ad;
int begin_ad = -1, pre2;
vis[abs(nod[start_ad].key)] = true;
for(int i = 1; i < n; i++) {
next = nod[pre].nextad;
if(vis[abs(nod[next].key)]) {
if(-1 == nod[next].nextad) {//删除最后一个节点
nod[pre].nextad = -1;
}else {
nod[pre].nextad = nod[next].nextad;
}
//刚删除的节点一定要将其后继地址赋值为-1
nod[next].nextad = -1;
if(-1 == begin_ad) {//第一次删除节点
begin_ad = next;
pre2 = begin_ad;
}else {
nod[pre2].nextad = next;
pre2 = next;
}
}else {
pre = next;
vis[abs(nod[pre].key)] = true;
}
}
_output(start_ad);
_output(begin_ad);
}
return 0;
}