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 (≤10^5 ) 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.
思路与样例
我的思路比较笨,就是模拟链表,正好熟悉下链表操作,注释应该很详细了。这里主要给出一个样例,你先可以试试书上的样例,如果不行再看我的,因为我书上的样例能过但是有一个答案错误。看到网上比较聪明的方法就是,按照链表顺序把节点放到一个vector或者数组里面,然后用头文件algorithm里的reverse函数一节一节地翻转就完事儿了,我就不贴代码了。
11111 5 4
11111 1 22222
22222 3 33333
33333 4 -1
44444 5 55555
55555 2 11111
代码
#include <cstdio>
using namespace std;
struct Node{
int data, Next;
}Nodes[100010];
int main(){
int start, N, K;
scanf("%d%d%d", &start, &N, &K);
for(int i = 0; i < N; i++){
int address;
scanf("%d", &address);
scanf("%d", &Nodes[address].data);
scanf("%d", &Nodes[address].Next);
}
//cnt记录已经完成操作的节点个数,K个为一组,以为倍数
//begin为组的开始下标
//last是上一组的第一个元素
int cnt = 0, begin = start, end = start, last;
//还有没有完成操作的组
while(true){
//iterator用来遍历链表,before用来记录原序列中当前节点的前一个节点
int iterator = begin, before = begin;
//找这一组的最后一个节点
end = begin;
for(int i = 0; i < K - 1 && end != -1; i++)
end = Nodes[end].Next;
//如果end是-1说明这一组个数不足K,此时不调整顺序
if(end == -1)
break;
//上一组最后一个节点连接这一组调整后的第一个节点
//从第二组开始
if(cnt > 0)
Nodes[last].Next = end;
last = begin;//记录这一组调整后的最后一个元素
//第一组的最后一个元素为整个链的首节点
if(cnt == 0)
start = end;
//修改begin为下一组第一个节点
begin = Nodes[end].Next;
for(int i = 0; i < K; i++){
int tmp = Nodes[iterator].Next;//用来保存修改next之前的next
if(i != 0)
Nodes[iterator].Next = before;
before = iterator;
iterator = tmp;
}
cnt += K;
}
//防止最后一组不用调整,此时上一组的最后节点接该组第一个节点(未调整)
if(cnt > 0)
Nodes[last].Next = begin;
for(int i = 0; i < N && start != -1; i++){
if(i < N - 1 && Nodes[start].Next != -1)
printf("%05d %d %05d\n", start, Nodes[start].data, Nodes[start].Next);
else
printf("%05d %d -1\n", start, Nodes[start].data);
start = Nodes[start].Next;
}
return 0;
}