pat 1074. Reversing Linked List (25)

题目地址:http://pat.zju.edu.cn/contests/pat-a-practise/1074

题目意思比较容易理解,

有几个需要注意的点:

1,如果不能整除,最后几个不用反转。

2,输入中可能有不在链表中的点。

我的解法就是以空间换时间的方法,具体代码如下:

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

//ifstream in("1074.txt");
//#define cin in

typedef struct listNode
{
	int key;
	int addr;
}listNode;


int nextAddr[100005];
int Key[100005];

vector<listNode> a;


int main()
{
	int begin,N,k;

	
	cin >> begin >> N >>k;

	int i;
	for(i = 0;i<N;i++)
	{
		int address;
		cin >> address;
		cin >> Key[address] >> nextAddr[address];
	}

	while(begin != -1)   //找出在一个链表上的元素。
	{
		listNode temp;
		temp.key = Key[begin];
		temp.addr = begin;
		begin = nextAddr[begin];
		a.push_back(temp);
	}

	int num = a.size() / k;  //此处必须这样用,不能用N
	
	vector<listNode>::iterator iter = a.begin();
	for(i = 0;i<num;i++)
	{
		int start = i*k;
		int end = (i+1)*k;
		reverse(iter+start,iter+end);  //反转函数
	}

	for(i = 0;i < a.size()-1;i++)
			printf("%05d %d %05d\n",a[i].addr,a[i].key,a[i+1].addr);
	
	printf("%05d %d -1\n",a[i].addr,a[i].key);
	

	return 0;

}


当然可以!下面是**完整的、可以直接提交的 C++ 源代码**,适用于典型的“反转链表”类题目(如 PAT A1074 Reversing Linked List)。 --- ### ✅ 题目背景回顾: - 给你一堆乱序的链表节点,每个节点有:地址、数据、下一个地址 - 要求:从头遍历链表,将每 K 个节点为一组进行**局部反转** - 最后输出反转后的链表(保持物理顺序不变,只改逻辑顺序) --- ## ✅ 完整源代码(C++) ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; const int MAXN = 100000; // 最大节点数 // 定义每个节点的信息 struct Node { int data; // 节点数据 int next; // 下一个节点地址 } node[MAXN]; // 用数组模拟“抽屉柜”,node[addr] 存 addr 地址处的节点信息 int main() { // 读取头节点地址、总节点数、组长度 K int head, n, k; cin >> head >> n >> k; // 1. 读入所有节点信息,并存入对应地址的“抽屉” for (int i = 0; i < n; i++) { int addr, data, next; cin >> addr >> data >> next; node[addr].data = data; node[addr].next = next; } // 2. 从 head 开始,顺着 next 指针走一遍,收集真实访问顺序 vector<int> addrs; // 存放按链表顺序排列的地址 int p = head; while (p != -1) { addrs.push_back(p); p = node[p].next; } // 3. 每 K 个节点一组,进行局部反转(不足 K 不反转) for (int i = 0; i + k <= addrs.size(); i += k) { reverse(addrs.begin() + i, addrs.begin() + i + k); } // 4. 按新的逻辑顺序输出结果 for (int i = 0; i < addrs.size(); i++) { int addr = addrs[i]; printf("%05d %d ", addr, node[addr].data); // 输出当前地址和数据 if (i == addrs.size() - 1) { // 最后一个节点,下一个地址是 -1 puts("-1"); } else { // 否则,“下一个”是新顺序中的下一个地址 printf("%05d\n", addrs[i + 1]); } } return 0; } ``` --- ## 📌 输入样例: ``` 00100 6 3 00100 1 12309 12309 2 33218 33218 3 00000 00000 4 99999 99999 5 68237 68237 6 -1 ``` ## 📤 输出样例: ``` 33218 3 12309 12309 2 00100 00100 1 68237 68237 6 99999 99999 5 00000 00000 4 -1 ``` --- ## 🔍 关键点解释 | 代码片段 | 作用 | |--------|------| | `node[addr].data = data` | 把输入的数据存进对应地址的“抽屉”里 | | `while (p != -1)` | 顺着链表走到底,得到真实顺序 | | `vector<int> addrs` | 记录真实访问顺序的地址列表 | | `reverse(...)` | 对每 K 个元素进行反转 | | `printf("%05d")` | 确保地址输出为 5 位数字,不足补零 | --- ## ✅ 这段代码的特点 - ✅ 正确处理乱序输入 - ✅ 自动跳过中间数字(通过 `cin >> addr >> data >> next`) - ✅ 成功提取地址作为索引 - ✅ 支持 K 组反转 - ✅ 输出格式完全符合要求 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值