PAT 天梯赛 L2-002 链表去重

模拟单链表的增删操作

题目链接: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;
}
posted @ 2016-05-16 19:36  yinzm  阅读(1190)  评论(0编辑  收藏  举报