pat甲级真题分类--模拟链表

本文档介绍了三种链表操作:BlockReversing(块级反转)将链表每K个节点作为一个区块进行反转,MergingLinkedLists(合并链表)将两个已排序链表合并成一个,SplittingALinkedList(分割链表)按指定大小分隔链表。通过实例展示了如何使用C++实现这些复杂链表操作。
摘要由CSDN通过智能技术生成

7-2 Block Reversing (25 分)

Given a singly linked list L. Let us consider every K nodes as a block (if there are less than K nodes at the end of the list, the rest of the nodes are still considered as a block). Your job is to reverse all the blocks in L. For example, given L as 1→2→3→4→5→6→7→8 and K as 3, your output must be 7→8→4→5→6→1→2→3.

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 (≤N) which is the size of a block. 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, and Next is the position of the next node.
Output Specification:
Sample Input:

00100 8 3
71120 7 88666
00000 4 99999
00100 1 12309
68237 6 71120
33218 3 00000
99999 5 68237
88666 8 -1
12309 2 33218

Sample Output:

71120 7 88666
88666 8 00000
00000 4 99999
99999 5 68237
68237 6 00100
00100 1 12309
12309 2 33218
33218 3 -1

#include<iostream>
using namespace std;

const int maxn=100099;

struct node
{
    int address,data,next;
}Node[maxn],Node1[maxn],Node2[maxn];

int first,n,k;

int main()
{
    cin >> first >> n >> k;
    for(int i=0; i<n; i++)
    {
        int a;
        cin >> a;
        cin >> Node[a].data >> Node[a].next;
        Node[a].address=a;
    }

    int cnt=0;
    while(first!=-1)
    {
        Node1[cnt].address=Node[first].address;
        Node1[cnt].data=Node[first].data;
        Node1[cnt].next=Node[first].next;
        first=Node[first].next;
        cnt++;
    }

    bool flag=true;
    int cnt1=0;
    for(int i=n-n%k; i>=0; i-=k)
    {
        if(flag)
        {
            for(int j=i; j<=n-1; j++)
            {
                Node2[cnt1].address=Node1[j].address;
                Node2[cnt1].data=Node1[j].data;
                cnt1++;
            }
            flag=false;
        }
        else
        {
            for(int j=i; j<=i+k-1; j++)
            {
                Node2[cnt1].address=Node1[j].address;
                Node2[cnt1].data=Node1[j].data;
                cnt1++;
            }
        }
    }

    for(int i=0; i<cnt1; i++)
    {
        if(i==cnt1-1)
            printf("%05d %d -1",Node2[i].address,Node2[i].data);
        else
            printf("%05d %d %05d\n",Node2[i].address,Node2[i].data,Node2[i+1].address);
    }
    return 0;

}

7-2 Merging Linked Lists (25 分)

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;

const int N = 1e5 + 10;
int n, h1, h2;
int e[N], ne[N];            //e的下标是地址,元素是值;ne的下标是地址,元素是下个地址
vector<int> l1, l2;

int main() 
{
    scanf("%d%d%d", &h1, &h2, &n);
    
    while (n--) 
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        e[a] = b, ne[a] = c;
    }

    for (int i = h1; ~i; i = ne[i]) l1.push_back(i);
    for (int i = h2; ~i; i = ne[i]) l2.push_back(i);
    if (l1.size() <= l2.size()) swap(l1, l2);           //一直保持l1是长的
    
    reverse(l2.begin(), l2.end());      //翻转l2

    for (int i = 0, j = 0; i < l1.size(); i++)     //i去遍历l1,j去遍历l2
    {
        printf("%05d %d ", l1[i], e[l1[i]]);
        if (i & 1 && j < l2.size())          //i&1 = (i+1)%2==0
        {
            printf("%05d\n%05d %d ", l2[j], l2[j], e[l2[j]]);
            j++;
        }
        if (i + 1 == l1.size()) 
            printf("-1\n");
        else 
            printf("%05d\n", l1[i + 1]);
    }


    return 0;
}

Splitting A Linked List (25 分)


#include<iostream>
using namespace std;

const int maxn=100010;

int e[maxn],ne[maxn];

int first,n,k;

struct node
{
    int address;
    int data;
}Node[maxn];

int cnt;

int main()
{
    cin >> first >> n >> k;

    for(int i=0; i<n; i++)
    {
        int address;
        cin >> address;
        cin >> e[address] >> ne[address];
    }

    int first1,first2;
    first1=first2=first;

    while(first1!=-1)
    {
        if(e[first1]<0)
        {
            Node[cnt].address=first1;
            Node[cnt].data=e[first1];
            cnt++;
        }
        first1=ne[first1];
    }

    while(first2!=-1)
    {
        if(e[first2]<=k && e[first2]>=0)
        {
            Node[cnt].address=first2;
            Node[cnt].data=e[first2];
            cnt++;
        }
        first2=ne[first2];
    }

    while(first!=-1)
    {
        if(e[first]>k)
        {
            Node[cnt].address=first;
            Node[cnt].data=e[first];
            cnt++;
        }
        first=ne[first];
    }

    for(int i=0; i<cnt-1; i++)
        printf("%05d %d %05d\n",Node[i].address,Node[i].data,Node[i+1].address);

    printf("%05d %d -1\n",Node[cnt-1].address,Node[cnt-1].data);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值