PAT basic-level 1025 反转链表 笔记

这篇博客介绍了PAT基本级1025题的解决方案,涉及链表反转问题。博主分享了在解决过程中遇到的挑战,包括迭代器输出限制、代码效率优化以及结构体成员变量类型选择的影响。通过调整代码,博主实现了更优雅且高效的答案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1025. 反转链表 (25)

时间限制
300 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
给定一个常数K以及一个单链表L,请编写程序将L中每K个结点反转。例如:给定L为1→2→3→4→5→6,K为3,则输出应该为3→2→1→6→5→4;如果K为4,则输出应该为4→3→2→1→5→6,即最后不到K个元素不反转。

输入格式:

每个输入包含1个测试用例。每个测试用例第1行给出第1个结点的地址、结点总个数正整数N(<= 105)、以及正整数K(<=N),即要求反转的子链结点的个数。结点的地址是5位非负整数,NULL地址用-1表示。

接下来有N行,每行格式为:

Address Data Next

其中Address是结点地址,Data是该结点保存的整数数据,Next是下一结点的地址。

输出格式:

对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。

输入样例:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
输出样例:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1


一道折腾了很久的题目,这里记录下几个点:
1. 输出迭代器访问成员变量只能用cout,不能用printf
2. 有个测试用例一直超时,为了加速,将所有cout/cin换成了printf/scanf,添加了std::ios::sync_with_stdio(false),但还是超时,最后采取用空间换时间的做法,发现这样写代码更优雅
3. 定义结构体作为vector容器类型,其中有string类型的成员变量的话,不能用printf输出,最后是把所有成员变量类型换成了int,00100这样的输入同样可以用%d读取给int变量。输出用%05d,表示宽度为5,不满用0补足

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

struct da{
    int add;
    int data;
    int next;
};
int main(){
    std::ios::sync_with_stdio(false);

    int firadd = 0, n = 0, k = 0;
    scanf("%d %d %d", &firadd, &n, &k);
    if(firadd == -1){ //首地址为-1.直接输出  
        printf("-1\n");
        return 0;
    }

    vector<da> temp(100000);
    vector<da> d;

    da nmp;
    for(int i = 0; i < n; ++i){ 
        scanf("%d %d %d", &nmp.add, &nmp.data, &nmp.next);
        temp[nmp.add] = nmp;
    }
    for(int i = 0; i < n; ++i){
        if(firadd == -1)
            break;
        d.push_back(temp[firadd]);
        firadd = temp[firadd].next; 
    }

    int t = d.size()/k;
    for(int i = 0; i < t; ++i)  //t趟
        for(int j = 0; j < k/2; ++j){
            da temp = d[j+k*i];
            d[j+k*i] = d[k-1-j+k*i];
            d[k-1-j+k*i] = temp;
        }

    for(vector<da>::iterator it = d.begin(); it != d.end()-1; ++it)
        it->next = (it+1)->add;
    vector<da>::iterator endt = d.end()-1;
    endt->next = -1;

    for(int i = 0; i < d.size(); i++){ 
        if(d[i].next != -1) 
            printf("%05d %d %05d\n", d[i].add, d[i].data, d[i].next);
        else
            printf("%05d %d -1\n", d[i].add, d[i].data);
    }

    return 0; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值