zoukankan      html  css  js  c++  java
  • A1133. Splitting A Linked List

    Given a singly linked list, you are supposed to rearrange its elements so that all the negative values appear before all of the non-negatives, and all the values in [0, K] appear before all those greater than K. The order of the elements inside each class must not be changed. For example, given the list being 18→7→-4→0→5→-6→10→11→-2 and K being 10, you must output -4→-6→-2→7→0→5→10→18→11.

    Input Specification:

    Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤10^5) which is the total number of nodes, and a positive K (≤10^3). The address of a node is a 5-digit nonnegative integer, and NULL is represented by −1.

    Then N lines follow, each describes a node in the format:

    Address Data Next
    

    where Address is the position of the node, Data is an integer in [-10^5, 10^5], and Next is the position of the next node. It is guaranteed that the list is not empty.

    Output Specification:

    For each case, output in order (from beginning to the end of the list) the resulting linked list. Each node occupies a line, and is printed in the same format as in the input.

    Sample Input:

    00100 9 10
    23333 10 27777
    00000 0 99999
    00100 18 12309
    68237 -6 23333
    33218 -4 00000
    48652 -2 -1
    99999 5 68237
    27777 11 48652
    12309 7 33218
    

    Sample Output:

    33218 -4 68237
    68237 -6 48652
    48652 -2 12309
    12309 7 00000
    00000 0 99999
    99999 5 23333
    23333 10 00100
    00100 18 27777
    27777 11 -1

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef struct NODE{
        int data, addr, next, valid, greater, neg, rank;
        NODE(){
            valid = 0;
        }
    }node;
    node list[100001];
    int first, N, K;
    bool cmp(node a, node b){
        if(a.valid != b.valid){
            return a.valid > b.valid;
        }else{
            if(a.neg != b.neg)
                return a.neg > b.neg;
            else{
                if(a.greater != b.greater)
                    return a.greater < b.greater;
                else return a.rank < b.rank;
            }
        }
    }
    int main(){
        scanf("%d%d%d", &first, &N, &K);
        for(int i = 0; i < N; i++){
            int addr, data, next;
            scanf("%d%d%d", &addr, &data, &next);
            list[addr].addr = addr;
            list[addr].data = data;
            list[addr].next = next;
            if(data <= K)
                list[addr].greater = 0;
            else list[addr].greater = 1;
            if(data < 0)
                list[addr].neg = 1;
            else list[addr].neg = 0;
        }
        int cnt = 0, pt = first;
        while(pt != -1){
            list[pt].valid = 1;
            list[pt].rank = cnt;
            pt = list[pt].next;
            cnt++;
        }
        sort(list, list + 100000, cmp);
        for(int i = 0; i < cnt - 1; i++){
            list[i].next = list[i+1].addr;
            printf("%05d %d %05d
    ", list[i].addr, list[i].data, list[i].next);
        }
        printf("%05d %d -1
    ", list[cnt - 1].addr, list[cnt-1].data);
        cin >> N;
        return 0;
    }
    View Code

    总结:

    1、题意:将链表重新排序,要求负数在前,正数在后;同时给出一个正数K,要求小于等于K的数在前,大于K的数在后。至于没有先后关系的数,保持它们在原链表中的先后顺序(注意原链表的顺序不是输入顺序,而是遍历一边之后得到的节点顺序)。

    2、做法是使用静态链表,先遍历一遍链表,标注出合法节点。再进行排序,按照合法节点在前,非法节点在后;合法节点中,负数在前;同正负的,小于等于K的数在前。排序后发现似乎不是稳定排序,只好在之前遍历的时候加入一个rank记录每个节点的原始顺序,当两节点之间需要保持原始顺序时使用。

    3、在网上还看到一种做法更简便:将所有数分成(负无穷,0),[0,K], (K, 正无穷]三个区间,将不同段的节点依次放入结果数组中即可。
  • 相关阅读:
    offset家族
    $的符号封装
    操作字符串
    无缝滚动
    根据字符返回位置
    网页编码和解码
    小米手机案例
    字符串对象常用方法
    匀速运动案例
    Render Functions & JSX
  • 原文地址:https://www.cnblogs.com/zhuqiwei-blog/p/9553756.html
Copyright © 2011-2022 走看看