Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K=3, then you must output 3→2→1→6→5→4; if K=4, you must output 4→3→2→1→5→6.
Input Specification:
Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤105) which is the total number of nodes, and a positive K (≤N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.
Then N lines follow, each describes a node in the format:
Address Data Next
where Address is the position of the node, Data is an integer, and Next is the position of the next node.
Output Specification:
For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.
Sample Input:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
Sample Output:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
题目大意
给出一个链表,长度为L,每K个数倒序输出(一共L/K组),剩余L%K个数顺序输出。
思路
用next数组和data数组存储每个结点的相应数值,下标为结点地址。由于给出的结点中可能存在多余结点,即不属于所给链表的结点,我首先根据首结点first和每个结点的next计算链表长度L。然后, 每K个数进行一次倒序输出(不包括K=1的情况),剩余的直接输出。
AC代码
#include <cstdio>
#include <iostream>
using namespace std;
#define maxn 100010
int main(){
int data[maxn], next[maxn];
int first, n, k;
scanf("%d%d%d", &first, &n, &k);
int add;
for(int i = 0; i < n; i++){
scanf("%d", &add);
scanf("%d%d", &data[add], &next[add]);
}
n = 0; //计算结点个数
int temp = first;
while(temp != -1){
n++;
temp = next[temp];
}
int p = next[first];
int s, pre = first; //s指向p的后继,pre指向前驱
int cnt = 0; //接受处理的元素数量
while(cnt + k <= n && k != 1){
for(int i = 0; i < k - 1; i++){
s = next[p];
next[p] = pre;
pre = p;
p = s;
}
p = pre;
cnt += k;
if(cnt != k)
printf("%05d\n", p);
for(int i = 0; i < k; i++){
printf("%05d %d ", p, data[p]);
if(i == k - 1 && cnt == n)
printf("-1\n");
else if(i != k - 1)
printf("%05d\n", next[p]);
p = next[p];
}
pre = s, p = next[pre];
}
if(pre != -1){ //未处理完,剩余直接输出
p = pre;
if(cnt != 0)
printf("%05d\n", p);
while(next[p] != -1){
printf("%05d %d %05d\n", p, data[p], next[p]);
p = next[p];
}
printf("%05d %d -1", p, data[p]);
}
return 0;
}