写的很啰嗦。。。
大概思路:先把非法的结点除去。拿到k个结点,对这k个结点的下一个地址进行修改,这k个结点反转后的最后一个(正常情况下的第一个)的下一个地址有可能是两种情况。第一种:取完k个结点后剩余不足k个,那么下一个地址就是第k+1个结点的地址;第二种:剩余结点大于等于k,那么下一个地址就是第2k个结点的地址。
实现
#include <iostream>
#include <cstdio>
#include <vector>
#define MAXSIZE 100005
using namespace std;
struct node {
int add,data, next;
};
int main()
{
int start, N, K,add,data,next,i,temp;
cin >> start >> N >> K;
vector<node> nodes(MAXSIZE);
vector<node> input(MAXSIZE);
for (i = 0; i < N; i++)
{
cin >> temp;
cin >> input[temp].data >> input[temp].next;
}
int n = 0,run=start;
while (n < N)
{
if (run == -1)
break;
nodes[run].add = run;
nodes[run].data = input[run].data;
nodes[run].next = input[run].next;
run= input[run].next;
n++;
}
//#############
int partstart = start, count = 0, partend;
while (n >= K)
{
vector<int> partadd(K);
partend = partstart;
count = 1;
while (count < K)
{
partadd[count++] = partstart;
if (partstart == -1)
continue;
partstart = nodes[partstart].next;
}
int pn = n - count>0 ? nodes[partstart].next : partstart;
int nextstart = pn;
if ((n - K) >= K)
{
i = 1;
for (i = 1; i < K; i++) pn = nodes[pn].next;
}
partadd[0] = pn;
for (; count >= 1; count--)
{
int tempadd = partadd[count - 1];
if (n == 1)
printf("%05d %d -1\n", nodes[partstart].add, nodes[partstart].data);
else
printf("%05d %d %05d\n", nodes[partstart].add, nodes[partstart].data, tempadd);
partstart = tempadd;
n--;
}
partstart = nextstart;
}
while (n)
{
if (nodes[partstart].next == -1)
{
printf("%05d %d -1\n", nodes[partstart].add, nodes[partstart].data);
break;
}
else
printf("%05d %d %05d\n", nodes[partstart].add, nodes[partstart].data, nodes[partstart].next);
partstart = nodes[partstart].next;
n--;
}
return 0;
}