1025. 反转链表 (25)
时间限制
300 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue
给定一个常数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是下一结点的地址。
输出格式:
对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。
输入样例: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
思路:
输入的是5位的非负整数,所以直接用int型保存,用%05d保持前导0输出就可以了,这样地址就可以直接是地址下标。然后计算有效节点个数(题意没说,刚开始没有计算有效节点个数,一直错最后一组数据),因为是根据k的值反转链表,所以就cnt刚开始初始化为k,因为第一位刚好对应反转后的第k位,后面只需要cnt递减,i递增,当i == k时 cnt 就要重新计算了计算公式为: cnt = k * (i / k + 1);
/* PAT https://www.patest.cn/contests/pat-b-practise/1025 注意输入可能有无效节点,如第七个节点并不在链表上 00100 7 4 00000 4 99999 00100 1 12309 68237 6 -1 33218 3 00000 99999 5 68237 12309 2 33218 55555 8 44444 */ #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <string> using namespace std; #define maxn (int)1e6+5 struct Node{ int add;//格式化 %05d输出就好 int x; int next; }arr[maxn], ans[maxn]; int main(){ int root, n, k; int count_node;//计算有效节点的个数 while (cin >> root >> n >> k && n) { count_node = 0; int data, to, ad; for (int i = 0; i < n; i++){ cin >> ad >> data >> to; arr[ad].add = ad; arr[ad].next = to; arr[ad].x = data; } ad = root; while (ad != -1){ count_node++; ad = arr[ad].next; } ad = root; int cnt = k; for (int i = 1;i <= count_node; i++){ ans[cnt--] = arr[ad]; ad = arr[ad].next; if (i % k == 0){ cnt = k * (i / k + 1); if (i + k > count_node){ while (i <= count_node) { ans[++i] = arr[ad]; ad = arr[ad].next; } } } } for (int i = 1; i < count_node; i++) { printf("%05d %d %05d\n", ans[i].add, ans[i].x, ans[i + 1].add); } printf("%05d %d -1\n", ans[count_node].add, ans[count_node].x); } return 0; }