给定一个单链表 L,我们将每 K 个结点看成一个区块(链表最后若不足 K 个结点,也看成一个区块),请编写程序将 L 中所有区块的链接反转。例如:给定 L 为 1→2→3→4→5→6→7→8
,K 为 3,则输出应该为 7→8→4→5→6→1→2→3
。
输入格式:
每个输入包含 1 个测试用例。每个测试用例第 1 行给出第 1 个结点的地址、结点总个数正整数 N (≤10^5)、以及正整数 K (≤N),即区块的大小。结点的地址是 5 位非负整数,NULL
地址用 −1
表示。
接下来有 N 行,每行格式为:
Address Data Next
其中 Address
是结点地址,Data
是该结点保存的整数数据,Next
是下一结点的地址。
输出格式:
对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。
输入样例:
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
输出样例:
71120 7 88666
88666 8 00000
00000 4 99999
99999 5 68237
68237 6 00100
00100 1 12309
12309 2 33218
33218 3 -1
|代码长度限制 | 时间限制 | 内存限制 |
| 16KB | 400ms | 64MB |
代码:
#include<bits/stdtr1c++.h>
using namespace std;
struct node {
int adress, data, next;
} N[100005];
vector<node> v1, v2;
int main() {
int first, n, k;
cin >> first >> n >> k;
for (int i = 0, t; i < n; i++) {
cin >> t;
N[t].adress = t;
cin >> N[t].data >> N[t].next;
}
while (first != -1) {
v1.emplace_back(N[first]);
first = N[first].next;
} //使链表有序
int t = int(v1.size()) / k, cnt = 0, j = 0;
vector<node> List[t + 1]; //使用二维数组对序列进行分组,方便后面反转
for (int i = 0; i < int(v1.size()); i++) {
List[j].emplace_back(v1[i]);
cnt++;
if (cnt == k) {
cnt = 0, j++; //当cnt与k相等时进入下一组
}
}
for (int a = j; a >= 0; a--) { //反转操作
for (int b = 0; b < int(List[a].size()); b++) {
v2.emplace_back(List[a][b]); //将反转的序列元素加入v3中
}
}
int len = v2.size();
for (int i = 0; i < len; i++) {
if (i != len - 1) v2[i].next = v2[i + 1].adress; //重新调整每个节点的当前地址和后继地址
else v2[i].next = -1;
}
for (int i = 0; i < len; i++) {
if (i != len - 1) printf("%05d %d %05d\n", v2[i].adress, v2[i].data, v2[i].next);
else printf("%05d %d -1", v2[i].adress, v2[i].data);
}
return 0;
}