zoukankan      html  css  js  c++  java
  • b_pat_分享 & 链表排序 & 链表去重(链表模拟)

    sharing


    思路
    照常输入,然后先遍历第一个链表,且将第一个链表的结点都的属性设置为访问过vis=true;再从第二条链表的开头开始遍历,遇到第一个vis=true的结点node则输出node.val,返回

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+5;
    struct node {
        int next=-1, vis;
    } A[N];
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        int s1,s2,n,addr,next;; cin>>s1>>s2>>n;
        char val;
    
        for (int i=0; i<n; i++) {
            cin>>addr>>val>>next;
            A[addr]={next, false};
        }
        for (int i=s1; i!=-1; i=A[i].next) A[i].vis=1;
        for (int i=s2; i!=-1; i=A[i].next) if (A[i].vis) {
            return printf("%05d", i), 0;
        }
        printf("-1");
        return 0;
    }
    

    Linked List Sorting

    第一行首先包含一个整数 N,表示总节点数量,然后包含链表头节点的地址。
    接下来 N 行,每行描述一个节点的信息,格式如下:
    Address Key Next
    其中 Address 是节点地址,Key 值是一个整数,Next 是下一个节点的地址。
    现在,给出一个链表,请你按照 Key 值升序的顺序将链表重新排序。
    思路
    投机取巧将node全部弄到一个vector中排序,信誓旦旦地写啦,但打的时候忘记了这样排序A[i]的next还是原来的next(即未排序时的指向),所以输出的时候输出A[i+1]的addr

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6;
    struct node {
        int addr, val, next=-1;
    } A[N];
    bool cmp(node& a, node& b) {
        return a.val<b.val;
    }
    vector<node> l_sort(int head_addr) {
        vector<node> v; 
        for (int i=head_addr; i!=-1; i=A[i].next) {
            v.push_back(A[i]);
        }
        sort(v.begin(), v.end(), cmp);
        return v;
    }
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        int n,head_addr; cin>>n>>head_addr;
        for (int i=0; i<n; i++) {
            int addr, val, next; cin>>addr>>val>>next;
            A[addr]={addr, val, next};
        }
        auto v=l_sort(head_addr);
        if (v.empty()) {
            printf("0 -1");
        } else {
            printf("%d %05d
    ", v.size(), v[0].addr);
            for (int i=0; i<v.size(); i++) {
                if (i==v.size()-1)  printf("%05d %d -1
    ", v[i].addr, v[i].val);
                else                printf("%05d %d %05d
    ", v[i].addr, v[i].val, v[i+1].addr);
            }
        }
        return 0;
    }
    

    Reversing Linked List

    给定一个常数 K 和一个单链表 L,请你在单链表上每 K 个元素做一次反转,并输出反转完成后的链表。
    如果链表最后一部分不足 K 个元素,则最后一部分不翻转。

    思路
    这题不能一边输入一边将节点push到vector中,因为你不知道哪个是头部结点,所以要输入完毕后再从头指针开始找结点

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6;
    struct node {
        int addr, val, next=-1;
    } A[N];
    void reverse_k(vector<node>& v, int l, int r) {
        while (l<r) {
            swap(v[l], v[r]);
            l++, r--;
        }
    }
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        int head_addr, n, k; cin>>head_addr>>n>>k;
    
        vector<node> v;
        for (int i=0; i<n; i++) {
            int addr,data,next; cin>>addr>>data>>next;
            A[addr]={addr,data,next};
        }    
        int p=head_addr;
        while (p!=-1) {
            v.push_back(A[p]);
            p=A[p].next;
        }
        for (int i=0; i+k-1<v.size(); i+=k) reverse_k(v,i,i+k-1);
        for (int i=0; i<v.size(); i++) {
            if (i==v.size()-1) printf("%05d %d -1
    ", v[i].addr, v[i].val);
            else printf("%05d %d %05d
    ", v[i].addr, v[i].val, v[i+1].addr);
        }
        return 0;
    }
    

    Deduplication on a Linked List

    给定一个单链表 L,链表上的每个节点都存有一个键值,你应该删掉其中拥有重复键值绝对值的节点。
    也就是说,对于每个值 K,只保留键值或键值绝对值为 K 的第一个节点。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+5;
    struct node {
        int addr, val, next=-1;
    } A[N];
    bool vis[N];
    vector<node> ans;
    vector<node> remove_and_get_dup(vector<node>& v) {
        vector<node> dup;
        for (int i=0; i<v.size(); i++) {
            if (vis[abs(v[i].val)]) {
                dup.push_back(v[i]);
            } else {
                vis[abs(v[i].val)]=1;
                ans.push_back(v[i]);
            }
        }
        return dup;
    }
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        int head_addr, n; cin>>head_addr>>n;
        for (int i=0; i<n; i++) {
            int addr,data,next; cin>>addr>>data>>next;
            A[addr]={addr,data,next};
        }
        vector<node> v;
        int p=head_addr;
        while (p!=-1) {
            v.push_back(A[p]);
            p=A[p].next;
        }
        auto dup=remove_and_get_dup(v);
        for (int i=0; i<ans.size(); i++) {
            if (i!=ans.size()-1) printf("%05d %d %05d
    ", ans[i].addr, ans[i].val, ans[i+1].addr);
            else printf("%05d %d -1
    ", ans[i].addr, ans[i].val);
        }
        for (int i=0; i<dup.size(); i++) {
            if (i!=dup.size()-1) printf("%05d %d %05d
    ", dup[i].addr, dup[i].val, dup[i+1].addr);
            else printf("%05d %d -1
    ", dup[i].addr, dup[i].val);
        }
        return 0;
    }
    

    Splitting A Linked List

    给定一个单链表,请编写程序将链表元素进行分类排列,使得所有负值元素都排在非负值元素的前面,而 [0,K] 区间内的元素都排在大于 K 的元素前面。
    但每一类内部元素的顺序是不能改变的。
    例如:给定链表为 18→7→-4→0→5→-6→10→11→-2,K 为 10,则输出应该为 -4→-6→-2→7→0→5→10→18→11
    思路
    用三个vector分别存各类元素最后的输出很麻烦,直接遍历3次原始vector更简单

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+5;
    struct node {
        int addr, val, next=-1;
    } A[N];
    vector<node> rearrange(vector<node>& v, int k) {
        vector<node> ans;
        for (int i=0; i<v.size(); i++) if (v[i].val<0) ans.push_back(v[i]);
        for (int i=0; i<v.size(); i++) if (v[i].val>=0 && v[i].val<=k) ans.push_back(v[i]);
        for (int i=0; i<v.size(); i++) if (v[i].val>k) ans.push_back(v[i]);
        return ans;
    }
    int main() {
        std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        int head_addr, n, k; cin>>head_addr>>n>>k;
        for (int i=0; i<n; i++) {
            int addr,data,next; cin>>addr>>data>>next;
            A[addr]={addr,data,next};
        }
        vector<node> v;
        int p=head_addr;
        while (p!=-1) {
            v.push_back(A[p]);
            p=A[p].next;
        }
        auto ans=rearrange(v, k);
        for (int i=0; i<ans.size(); i++) {
            printf("%05d %d", ans[i].addr, ans[i].val);
            if (i!=ans.size()-1) printf(" %05d
    ", ans[i+1].addr);
            else printf(" -1
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    【转载】 HTTP 中 GET 与 POST 的区别
    JS 浏览器cookie的设置,读取,删除
    JS Event事件流(冒泡机制、捕获机制、事件绑定)
    DOM节点树和元素树--深度遍历
    Html_Task4(知识点:水平居中+垂直居中/position/float/border-radius)
    百度前端技术学院—斌斌学院题库
    百度前端技术学院—-小薇学院(HTML+CSS课程任务)
    js正则表达式
    js设计模式(一)发布订阅模式
    vue学习笔记(一)——利用vue-cli搭建一个前端项目
  • 原文地址:https://www.cnblogs.com/wdt1/p/13726800.html
Copyright © 2011-2022 走看看