PAT(甲级)2019年冬季考试 7-2 Block Reversing (25分)——模拟链表

╰半夏微凉° 2023-02-19 10:25 113阅读 0赞

7-2 Block Reversing (25分)

Given a singly linked list L. Let us consider every K nodes as a block (if there are less than K nodes at the end of the list, the rest of the nodes are still considered as a block). Your job is to reverse all the blocks in L. For example, given L as 1→2→3→4→5→6→7→8 and K as 3, your output must be 7→8→4→5→6→1→2→3.

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 (≤10​5) which is the total number of nodes, and a positive K (≤N) which is the size of a block. 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:

  1. Address Data Next

where Address is the position of the node, Data is an integer, and Next is the position of the next node.

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:

  1. 00100 8 3
  2. 71120 7 88666
  3. 00000 4 99999
  4. 00100 1 12309
  5. 68237 6 71120
  6. 33218 3 00000
  7. 99999 5 68237
  8. 88666 8 -1
  9. 12309 2 33218

Sample Output:

  1. 71120 7 88666
  2. 88666 8 00000
  3. 00000 4 99999
  4. 99999 5 68237
  5. 68237 6 00100
  6. 00100 1 12309
  7. 12309 2 33218
  8. 33218 3 -1

题意:

给定一个单链链表L,让我们把每个K个节点看作一个块(如果列表末尾的节点少于K个,那么其余的节点仍然被看作一个块)。你的工作是反转L中的所有块。例如,给定L为1→2→3→4→5→6→7→8和K为3,你的输出必须是7→8→4→5→6→1→2→3。

输入规格:
每个输入文件包含一个测试用例。对于每种情况,第一行包含第一节点的地址、节点总数的正N(≤105)和块大小的正K(≤N)。节点的地址是一个5位非负整数,空值由-1表示。

接下来是N行,每行描述一个节点的格式为

  1. Address Data Next

其中Address是节点的位置,Data是整数,Next是下一个节点的位置。
输出规格:
对于每种情况,输出结果的有序链表。每个节点占用一行,并以与输入相同的格式打印。

代码:

1. 解法一(来源于网络)
使用sort的方法巧妙将链表反转:三阶排序:1.is0k 2.group 3.index
对于这道题来说,主要是group比较重要,在Node的结构里直接加入{group、index},初始化后进行排序!

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <vector>
  4. using namespace std;
  5. struct Node {
  6. int data,address,next;
  7. int isOk;
  8. int group, index;
  9. Node (){
  10. isOk=0;
  11. }
  12. }node[100010];
  13. bool cmp(Node a, Node b){
  14. if (a.isOk!=b.isOk) return a.isOk>b.isOk;
  15. else if (a.group!=b.group) return a.group>b.group;
  16. else return a.index<b.index;
  17. }
  18. int main(){
  19. int n,k;
  20. int begin;
  21. scanf("%d %d %d",&begin, &n, &k);
  22. for (int i=0; i<n; i++){
  23. int address, data, next;
  24. scanf("%d %d %d",&address, &data, &next);
  25. node[address].data=data;
  26. node[address].address=address;
  27. node[address].next=next;
  28. }
  29. int p=begin;
  30. int cnt=0;
  31. //group a[group][index]
  32. while (p!=-1){
  33. node[p].group=cnt/k;
  34. node[p].index=cnt%k;
  35. cnt++;
  36. node[p].isOk=1;
  37. p=node[p].next;
  38. }
  39. sort(node, node+100010, cmp);
  40. for (int i=0; i<cnt; i++){
  41. if (i!=cnt-1){
  42. printf("%05d %d %05d\n",node[i].address, node[i].data, node[i+1].address);
  43. }else {
  44. printf("%05d %d -1\n",node[i].address, node[i].data);
  45. }
  46. }
  47. return 0;
  48. }

2. 解法二(来源于网络)

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int maxn = 100010;
  4. struct Node
  5. {
  6. int data, nex;
  7. }node[maxn];
  8. void Print(const vector<int> & ans)
  9. {
  10. if(ans.size() == 0)
  11. {
  12. printf("0 -1");
  13. }else
  14. {
  15. for(int i = 0; i < ans.size(); ++i)
  16. {
  17. if(i < ans.size() - 1) printf("%05d %d %05d\n", ans[i], node[ans[i]].data, ans[i+1]);
  18. else printf("%05d %d -1\n", ans[i], node[ans[i]].data);
  19. }
  20. }
  21. }
  22. int main()
  23. {
  24. int first, n, k;
  25. scanf("%d %d %d", &first, &n, &k);
  26. for(int i = 0; i < n; ++i)
  27. {
  28. int ad;
  29. scanf("%d", &ad);
  30. scanf("%d %d", &node[ad].data, &node[ad].nex);
  31. }
  32. int head = first, cnt = 1;
  33. vector<vector<int> > tmp;
  34. vector<int> tmp2, ans;
  35. while(head != -1)
  36. {
  37. tmp2.push_back(head);
  38. if(cnt % k == 0 || node[head].nex == -1)
  39. {
  40. tmp.push_back(tmp2);
  41. tmp2.clear();
  42. }
  43. cnt++;
  44. head = node[head].nex;
  45. }
  46. for(int i = tmp.size()-1; i >= 0; --i)
  47. {
  48. for(int j = 0; j < tmp[i].size(); ++j)
  49. {
  50. ans.push_back(tmp[i][j]);
  51. }
  52. }
  53. Print(ans);
  54. return 0;
  55. }

3. 解法三(来源于网络)

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<vector>
  4. #include<map>
  5. #include<string>
  6. #include<set>
  7. #include<cctype>
  8. #include<algorithm>
  9. using namespace std;
  10. const int INF = 0x3fffffff;
  11. const int maxn = 100010;
  12. struct node{
  13. int address,data,next,flag;
  14. node(){
  15. flag = -1;
  16. }
  17. }Node[maxn];
  18. bool cmp1(node a,node b){
  19. return a.flag > b.flag;
  20. }
  21. bool cmp2(node a,node b){
  22. return a.flag < b.flag;
  23. }
  24. int main(){
  25. int start,n,k;
  26. scanf("%d%d%d",&start,&n,&k);
  27. for(int i = 0; i < n; i++){
  28. int add;
  29. scanf("%d",&add);
  30. scanf("%d%d",&Node[add].data,&Node[add].next);
  31. Node[add].address = add;
  32. }
  33. int cnt = 0;
  34. for(int p = start; p != -1; p = Node[p].next){
  35. Node[p].flag = cnt++;
  36. }
  37. sort(Node,Node+maxn,cmp1);
  38. int temp = cnt % k;
  39. if(temp != 0){
  40. sort(Node,Node+temp,cmp2);
  41. }
  42. for(int i = temp; i + k <= cnt; i+=k){
  43. sort(Node+i,Node+i+k,cmp2);
  44. }
  45. for(int i = 0; i < cnt; i++){
  46. if(i != cnt - 1)
  47. printf("%05d %d %05d\n",Node[i].address,Node[i].data,Node[i+1].address);
  48. else printf("%05d %d -1\n",Node[i].address,Node[i].data);
  49. }
  50. }

发表评论

表情:
评论列表 (有 0 条评论,113人围观)

还没有评论,来说两句吧...

相关阅读