分数 25
作者 陈越
单位 浙江大学
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.
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.
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.
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
C++ (g++)
用Data数组存数值,用Next数组存下一节点的地址,两个都以当前节点的地址为下标,同时记录了值,地址值,下一节点的地址。
用OriAdr数组用来存输入数据的地址值
开一个vector容器用来存反转后节点的地址,然后根据这个地址下标,输出地址、值、下一节点的地址。
Read(int *Data,int * Next, int N) 读入数据
Print_Format (int num) 格式化输出五位数地址
Reverse(int * Data,int * Next,int first,int K)
逆置链表
首先记录节点的个数
然后根据个数确定够不够K,逆不逆置
如果不能逆置的话,直接将剩下的节点地址值存入Ans中
如果能逆置的话,将这一组节点的地址值倒序压入Ans中
如果遍历完整个链表节点的话,退出循环。
输出逆置后的链表
注意结尾不能有多余空格
主函数就很简单。
#include
using namespace std;
#define maxsize 100005
int Data[maxsize];
int Next[maxsize];
int OriAdr[maxsize];//输入顺序的地址
vector<int> Ans;//反转后节点的地址
void Read(int *Data,int *Next, int N)
{
for(int i=0;i<N;i++)
{
int address,data,next;
cin>>address>>data>>next;
Data[address]=data;//以地址为下标
Next[address]=next;
}
}
void Print_Format(int num)
{
//格式化输出五位地址数
if(num==-1) {cout<<-1;return;}
int d=10000;
for(int i=0;i<5;i++)
{
int temp=num/d;
while(temp/10!=0) temp=temp%10;
cout<<temp;
d/=10;
}
}
void Reverse(int* Data,int* Next,int first,int K)
{
int temp=first;
int cnt=0;
//计算有效节点,题目所给有些节点是多余的
while(temp!=-1)
{
cnt++;
OriAdr[cnt]=temp;
temp =Next[temp];//按照链表地址顺序索引
}
for(int i=0;;i+=K)
{
//若剩余节点不足k,则将余下节点按照顺序加入Ans中
if(i+K>cnt)
{
i++;//从第i+1个节点开始
while(i<=cnt)
{
Ans.push_back(OriAdr[i]);
i++;
}
break;
}
int j=i+K;
while(j>i)
{
Ans.push_back(OriAdr[j]);
j--;
}
if(i+K==cnt) break;
}
for(auto it=Ans.begin();it!=Ans.end();it++)
{
Print_Format(*it);
cout<<" "<<Data[*it]<<" ";
if(it+1==Ans.end()) cout<<-1;
else
{
Print_Format(*(it+1)); cout<<endl;
}
}
}
int main()
{
int first,N,K;//首地址,节点个数,反转个数
cin>>first>>N>>K;
Read(Data,Next,N);
Reverse(Data,Next,first,K);
return 0;
}