【PAT甲级】1074 Reversing Linked List (25分)

解题过程的小记录,如有错误欢迎指出。

难度:三星(需要考虑无效结点,还是不太习惯链表的思想orz)

小导航~

  • 题目分析
      • 注意点
  • 我的解题过程
      • 思路
      • bug
      • 代码
  • dalao的代码
      • 借鉴点

题目分析

给出一串数列,按指定的长度一小块一小块进行逆转,小于指定的长度多出来的部分保持原状,输出数列

注意点

题目中存在无效结点(不在链表之中),不考虑的话最后一个测试点无法通过

我的解题过程

思路

  1. 在输入的过程中采用静态链表存储信息,数字下标即为结点地址
  2. 输入完毕后,按照链表顺序插入一个vector数组(这里就自动去除掉了无效结点,更新一下结点总数n为数组的size)
  3. 对于数组进行一小块一小块的reverse
  4. reverse完毕后更新每个结点的next值
  5. 进行输出,最后一个-1的格式要注意一下

bug

刚开始没有用reverse函数,而是自己找规律改指针next,一片混乱

代码

#include
#include
#include

using namespace std;

struct Node {
	int address;
	int data;
	int next;//指向下一个地址
};

int main()
{
	vector<Node> nodes(100000), actual;
	int n, k, head;
	scanf("%d %d %d", &head, &n, &k);
	for (int i = 0; i < n; i++) {
		int address;
		scanf("%d", &address);
		nodes[address].address = address;
		scanf("%d %d", &nodes[address].data, &nodes[address].next);
	}
	int current = head;
	for (int i = 0; i < n; i++) {
		actual.push_back(nodes[current]);
		current = nodes[current].next;
		if (current == -1) break;//去除无效结点后的新n,当到结尾后就不要再插入了
	}
	n = actual.size();//去除无效结点后的新n
	for (int i = 0; i*k + k <= n; i++) {
		reverse(actual.begin() + i*k, actual.begin() + i*k + k);
	}
	current = actual[0].address;
	for (int i = 0; i < n - 1; i++) {
		actual[i].next = actual[i + 1].address;
	}
	actual[n - 1].next = -1;
	for (int i = 0; i < n; i++) {
		printf("%05d %d ", actual[i].address, actual[i].data);
		if (i != n - 1) printf("%05d\n", actual[i].next);
		else printf("-1\n");
	}
    return 0;
}

dalao的代码

全部代码因版权原因不放出来,大家可以自行去柳神博客购买或者参考晴神的上机笔记~

借鉴点

这题看自己的代码就好,晴神用了链表的概念,柳神直接用数组找规律了,emm还是喜欢自己的~

你可能感兴趣的:(PAT甲级)