给定一个常数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
这是第一次让我非常难过的一道乙级题,也让我学到了很多,我一开始编的程序虽然输入示例数据与示例输出一模一样,然而只通过了一个测试点,这说明了我这道题还有很多东西没有考虑到这道题让我们做链表,然而给我们的地址数据不是真实的内存地址,这个时候有一个办法就是可以去模拟一个内存空间,然后设定一个结点类或者结构体,通过结构体中的地址信息,给不同的结构体建立联系,将输入的一些节点连成链表,然后根据题意去处理链表中需要反转的部分,处理完以后最最重要的一部分,也是我最忽视的一部分就是,反转完了以后还要重新建立链表中结点的联系,把前一个节点的后地址只想后一个节点的地址,最后在输出才可以保证完美通过,如果是格式化输出,不能忽略最后一行不要将结点的-1格式化成5位数。以下是代码:
#include <iostream> #include <vector> using namespace std; struct node { int ads; int data; int nads; }; int main() { vector<node>spac(100000); vector<node> vec; vector<node> res; int firstadd; int N; int K; cin >>firstadd>> N >> K; node tmp; for (int i = 0; i < N; i++) { cin >> tmp.ads >> tmp.data >> tmp.nads; spac[tmp.ads] = tmp; } if (firstadd == -1) { printf("-1\n"); }else { int nextadd = firstadd; while (nextadd != -1) { vec.push_back(spac[nextadd]); nextadd = spac[nextadd].nads; } int N2 = vec.size(); int rdx = K - 1; while (rdx < N2) { for (int i = rdx; i > rdx - K; i--) { res.push_back(vec[i]); } rdx += K; } for (int i = rdx - K + 1; i < N2; i++) { res.push_back(vec[i]); } for (int i = 0; i < N2 - 1; i++) { res[i].nads = res[i+1].ads; printf("%05d %d %05d\n", res[i].ads, res[i].data, res[i].nads); } printf("%05d %d %d", res[N2 - 1].ads, res[N2 - 1].data, -1); } return 0; }
时间: 2024-10-01 12:28:54