PAT乙级1025

112 阅读2分钟

题目

image.png

是不是乍一看就是一个顺序表,其实也差不多,就运用顺序表。先定义一个结构体,就叫List,里面存放Address 是结点地址,Data 是该结点保存的整数数据,Next 是下一结点的地址。再输入每个结点的数据,再把顺序存入vector数组中。最后就可以每k个数就反转一次,末尾如果没有凑够k个数字,就不用反转。

代码

如下:

//foreverking
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;

typedef struct node{
    int address;//地址(下标)
    int data;//数据
    int next;//下一个元素的地址
}List;

int first,n, k;//first:首节点 n:总节点数 k:反转数
int main(){
    vector<List> v;
    List s[100000];
    cin >> first >> n >> k;
    for (int i = 0; i < n; i++) {
        //cin >> s[i].address >> s[i].data >> s[i].next;
        List l;
        cin >> l.address >> l.data >> l.next;
        s[l.address] = l;
    }

    //NULL 地址用 -1 表示
    int nextaddress = first;
    while(nextaddress != -1){//链表存入vector
        v.push_back(s[nextaddress]);
        nextaddress = s[nextaddress].next;//指针后移
    }
    vector<List>::iterator it = v.begin();//迭代器
    for(int i = 0; i < v.size() / k; i++){//可以凑够几次的反转,最后不到k的不反转
        reverse(it,it + k);//反转
        it = it + k;
    }
    for(int i = 0; i < v.size() - 1; i++){//输出
        printf("%05d %d %05d\n", v[i].address, v[i].data, v[i + 1].address);
    }
    printf("%05d %d -1\n", v[v.size()-1].address, v[v.size()-1].data); //打印最后一个节点
    return 0;

}

/*
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
 */

代码细节

首先是输入时,不能这样输入cin >> s[i].address >> s[i].data >> s[i].next;。这样会超时,但是具体原因我也不是很清楚。第二是迭代器的使用,通过迭代器可以读取它指向的元素,*迭代器名就表示迭代器指向的元素,迭代器就像指针,指向的是地址 vector<int>::iterator it; //定义正向迭代器.最后是用上好的反转函数reverse可以用。

其他方法

#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
    int first, k, n, temp;
    cin >> first >> n >> k;
    int data[100005], next[100005], list[100005];
    for (int i = 0; i < n; i++)
    {
        cin >> temp;
        cin >> data[temp] >> next[temp];
    }
    int sum = 0; //不一定所有的输入的结点都是有用的,加个计数器
    while (first != -1)
    {
        list[sum++] = first;
        first = next[first];
    }
    for (int i = 0; i < (sum - sum % k); i += k)
        reverse(begin(list) + i, begin(list) + i + k);
    for (int i = 0; i < sum - 1; i++)
        printf("%05d %d %05d\n", list[i], data[list[i]], list[i + 1]);
    printf("%05d %d -1", list[sum - 1], data[list[sum - 1]]);
    return 0;
}

柳婼的简短代码,没有使用结构体,使用两个数组分别存数据,下一个地址。再将表结点的各地址存入List数组。最后反转输出

题目链接