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.
给出一个常量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=3的情况下反转了123和456,K=4的情况下反转了1234,没有反转56。
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 (≤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.
每个输入文件包含一个测试用例。每个用例中,第一行包含了第一个结点的地址,结点的数量N(小于100000),要反转的子列的长度K(小于N)。节点的地址是一个5位的非负数的int,用-1代表NULL。
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.
Address是结点的位置,Data类型为int,Next是下一个节点的位置。
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.
按照顺序输出链表,每一个结点占一行,输出格式与输入格式一致。
Sample Input:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
Sample Output:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
测试点:
测试点 | 结果 | 得分/满分 | 用时(ms) | 内存(MB) | 要点提示 |
---|---|---|---|---|---|
测试点1 | 答案正确 | 12/12 | 2 | 1 | sample 有尾巴不反转, 地址取上下界 |
测试点2 | 答案正确 | 3/3 | 2 | 1 | 正好全反转 |
测试点3 | 答案正确 | 2/2 | 2 | 1 | K=N全反转 |
测试点4 | 答案正确 | 2/2 | 2 | 1 | K=1不用反转 |
测试点5 | 答案正确 | 2/2 | 2 | 1 | N=1 最小case |
测试点6 | 答案正确 | 3/3 | 94 | 4 | 最大N,最后剩K-1不反转 |
测试点7 | 答案正确 | 1/1 | 2 | 1 | 有多余结点不在链表上 |
思路:
#include <stdlib.h>
#include <stdio.h>
typedef struct node{
int Address;
int Data;
int Next;
} list;
void Array(list a[],int N,int headaddress); //先按序号排好
void Exchange(list a[],int i,int j); //交换两个元素的所有值
void Reverse(list a[],int N,int K); //每K个元素反转一次
int main()
{
int K,N,headaddress,eff;
scanf("%d %d %d",&headaddress,&N,&K);
list a[N];
for(int i=0;i<N;i++)
{
scanf("%d %d %d",&a[i].Address,&a[i].Data,&a[i].Next);
}
Array(a,N,headaddress);
for(int i=0;i<N;i++) //为了测试点7,只要反转到Next为-1的元素就行
{
if(a[i].Next==-1)
{
eff=i+1;
}
}
Reverse(a,eff,K);
for(int i=0;i<eff;i++) //根据每个元素的下一个元素的Address,修改每个元素的Next
{
a[i].Next=a[i+1].Address;
if(i==eff-1)
{
a[i].Next=-1;
}
}
for(int i=0;i<eff-1;i++)
{
printf("%05d %d %05d\n",a[i].Address,a[i].Data,a[i].Next);
}
printf("%05d %d %d\n",a[eff-1].Address,a[eff-1].Data,-1);
return 0;
}
void Array(list a[],int N,int headaddress)
{
for(int i=0;i<N;i++)
{
if(a[i].Address==headaddress)//找出第一个元素并和0号交换
{
Exchange(a,i,0);
break;
}
}
for(int i=0;i<N;i++)//遍历数组,找出Address和当前元素的Next一致的元素,并和下一个元素交换
{
for(int j=i+1;j<N;j++)
{
if(a[i].Next==a[j].Address)
{
Exchange(a,i+1,j);
break;
}
}
}
}
void Exchange(list a[],int i,int j)
{
list temp;
temp.Address=a[j].Address;
temp.Data=a[j].Data;
temp.Next=a[j].Next;
a[j].Address=a[i].Address;
a[j].Data=a[i].Data;
a[j].Next=a[i].Next;
a[i].Address=temp.Address;
a[i].Data=temp.Data;
a[i].Next=temp.Next;
}
void Reverse(list a[],int N,int K)
{
int cnt=N/K;
if(cnt)
{
for(int j=1;j<=cnt;j++) //在当前的K个元素中,交换第i个和第K-i个
{
for(int i=1;i<=K;i++)
{
if((j-1)*K+i-1<=j*K-i-1) //判断当前的K个元素是否都交换了
{
Exchange(a,(j-1)*K+i-1,j*K-i);
}
}
}
}
}