链接:https://www.nowcoder.com/questionTerminal/5f44c42fd21a42b8aeb889ab83b17ad0?f=discussion
来源:牛客网
给定一个常数K以及一个单链表L,请编写程序将L中每K个结点反转。例如:给定L为1→2→3→4→5→6,K为3,则输出应该为
3→2→1→6→5→4;如果K为4,则输出应该为4→3→2→1→5→6,即最后不到K个元素不反转。
输入描述:
每个输入包含1个测试用例。每个测试用例第1行给出第1个结点的地址、结点总个数正整数N(<= 105)、以及正整数K(<=N),即要求反转的 子链结点的个数。结点的地址是5位非负整数,NULL地址用-1表示。 接下来有N行,每行格式为: Address Data Next 其中Address是结点地址,Data是该结点保存的整数数据,Next是下一结点的地址。
输出描述:
对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。
难怪这题之前做的时候没啥头绪,手动构造链表真的是难到我了。参考了一下牛客的评论区,发现用地址做下标,会简化。
坑点:输入的节点中有无效节点。
#include <iostream>
#include<algorithm>>
#include<iomanip>
using namespace std;
#define Max 100002 //最大数字
int main()
{
int data[Max];
int next[Max];
int first, n, k;
cin >> first >> n >> k;//初始值的输入
int temp;//存放临时地址
for (int i = 0; i < n; i++)
{
cin >> temp;
cin >> data[temp];
cin >> next[temp];
}
int address[Max];
int num = 0;//有效节点的数量
while (first != -1)
{
address[num++] = first; //将地址按顺序存入地址数组
first = next[first];
}
int time = num / k;//需要反转几轮
for (int i = 0, j = 0; j < time; i = i + k, j++)//j控制循环次数,i控制间距
{
reverse(address + i, address + k + i);//依次反转
}
for (int i = 0; i < num - 1; i++)//按格式输出,地址依次存放。数据按下标找
{
cout << setw(5) << setfill('0') << address[i] << " "
<< data[address[i]] << " "
<< setw(5) << setfill('0') << address[i + 1] << endl;
}
//输出最后一个,他的next为默认的-1
cout << setw(5) << setfill('0') << address[num - 1] << " " << data[address[num - 1]] << " " << "-1" << endl;
return 0;
}