给定一个单链表 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 (≤105)、以及正整数 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
代码长度限制16 KB
时间限制400 ms
内存限制64 MB
第六个测试点大坑
输入可能出现多余结点,例如以下测试数据中真正有意义的链表节点少于输入的N
输入
33333 3 1
11111 10 -1
33333 30 22222
22222 20 -1
正确输出
22222 20 33333
33333 30 -1
这里如果忽视了多余节点的情况就可能出现这种错误结果
00000 0 22222
22222 20 33333
33333 30 -1
解决思路;
通过循环筛查找出真正有意义的链表结点长度
在后续用新的nodes存放筛查后的链表,避免整个代码都使用N进行计算
程序代码
#include<stdio.h>
#include<string.h>
typedef struct
{
int addr;
int data;
int next;
}Node;
int main()
{
int firstAddr, N, K, firstAddr1, k, len;
scanf("%d %d %d", &firstAddr, &N, &K);
Node nodes[100002];//下标为节点地址,用于输入地址
int addr;
int i, j;
for (i = 0; i < N; i++)
{
scanf("%d", &addr);
scanf("%d %d", &nodes[addr].data, &nodes[addr].next);
}
Node Nodes[100002];//下标从0到len,用于重新整理输出时的顺序
Nodes[0].addr = firstAddr;
Nodes[0].data = nodes[firstAddr].data;
Nodes[0].next = nodes[firstAddr].next;
for (i = 1; i < N; i++)
{
if (Nodes[i - 1].next != -1)
{
Nodes[i].addr = Nodes[i - 1].next;
Nodes[i].data = nodes[Nodes[i].addr].data;
Nodes[i].next = nodes[Nodes[i].addr].next;
}
else
{
break;
}
}
len = i;//防止出现多余结点,筛查有意义链表节点的长度
int c, d;//c存放区块数量,d存放最后一个不足K个结点的区块
c = len / K; d = len % K;
if (d != 0)
{
if (c != 0)
{
Nodes[len - 1].next = Nodes[len - K - d].addr;
Nodes[K - 1].next = -1;
}
else
Nodes[len - 1].next = -1;
}
else
{
Nodes[K - 1].next = -1;
}
for (i = c * K - 1, j = c * K - 2 * K; j >= 0; i = i - K, j = i - 2 * K + 1)
{
Nodes[i].next = Nodes[j].addr;//确定新的链表顺序
}
Node newnodes[100002];//下标为节点地址,使输出时用while函数更方便
for (k = 0; k < len; k++)
{
newnodes[Nodes[k].addr].addr = Nodes[k].addr;
newnodes[Nodes[k].addr].data = Nodes[k].data;
newnodes[Nodes[k].addr].next = Nodes[k].next;
}
if (c != 0)
i = (d == 0 ? len - K : len - d);
else
i = 0;
firstAddr1 = Nodes[i].addr;//输出时的第一个地址
while (firstAddr1 != -1)
{
if (newnodes[firstAddr1].next != -1)
printf("%05d %d %05d\n", newnodes[firstAddr1].addr, newnodes[firstAddr1].data, newnodes[firstAddr1].next);
else
printf("%05d %d -1\n", newnodes[firstAddr1].addr, newnodes[firstAddr1].data);
firstAddr1 = newnodes[firstAddr1].next;
}
return 0;
}