把一个链表切成长度为k的段,把每个段内节点原油的顺序反过来。
如果链表最后元素不满k个,这剩下的不满k个的元素就不用反序。
写的时候有很多细节问题,比如说,每个段反序之后的最后一个元素,应当指向下一个段的第一个元素,而下一个段的第一个元素,又要视情况而定,因为下一个段可能不需要反序。所以,每处理完一个段,还要保存一下这个段最后一个元素的地址,以便在处理下一个段的时候,把这个元素的指针指到下一个段的首元素去。但是如果这个段已经是最后一段了,就不能留到下一个段再处理了……还有,题目给了一个头,链表在经过处理以后,头可能会有变化,注意保存新头。
#include<cstdio>
#include<iostream>
using namespace std;
typedef struct node{
int valu,next;
node(){next=-1;}
}node;
node nd[100005];
int n,k;
int start,newstart;
int main(){
int i;
scanf("%d%d%d",&start,&n,&k);
int addr;
for(i=0;i<n;i++){
scanf("%d",&addr);
scanf("%d%d",&nd[addr].valu,&nd[addr].next);
}
if(k>1){
addr=start;
int stack[100005],cnt,temp,last=-2;
while(addr!=-1){
temp=addr;
for(cnt=0;cnt<k&&temp!=-1;cnt++){
stack[cnt]=temp;
temp=nd[temp].next;
}
if(cnt==k){//如果本段节点数满k个,则本段需要倒序
for(i=cnt-1;i>0;i--)
nd[stack[i]].next=stack[i-1];
}
if(temp==-1&&cnt==k)//如果本段是最后一段且本段需要倒序,则第一个节点要指向-1
nd[stack[0]].next=-1;
if(addr==start){//如果这个段是第一段,则需要置newstart
if(cnt<k)//整个序列都不用倒序的话,头就还是原来的头
newstart=start;
else
newstart=stack[cnt-1];
}
else{//如果不是第一段,那么需要置上一段的最后一个节点的next值
if(cnt==k)
nd[last].next=stack[cnt-1];
else
nd[last].next=stack[0];
}
if(cnt==k)
last=stack[0];
/*printf("$$$$\n");
for(i=0;i<cnt;i++)
printf("%05d %d %05d\n",stack[i],nd[stack[i]].valu,nd[stack[i]].next);
printf("$$$$\n");*/
addr=temp;
}
}
else
newstart=start;
addr=newstart;
//printf("~~~\n");
while(addr!=-1){
if(nd[addr].next!=-1)
printf("%05d %d %05d\n",addr,nd[addr].valu,nd[addr].next);
else
printf("%05d %d %d\n",addr,nd[addr].valu,nd[addr].next);
addr=nd[addr].next;
}
return 0;
}