一、题目
二、代码
#include <iostream>
#include <algorithm>
#include<vector>
#include<string>
using namespace std;
struct list {
int address, next, data;
};
int main() {
int firs, n, k;
cin >> firs >> n >> k;
vector<list> l(1000001);//不能正好为99999,会越界
//输入
int address1;
for (int i = 0; i < n; i++) {
cin >> address1;
cin >> l[address1].data;
cin >> l[address1].next;
l[address1].address = address1;
}
正序(next起作用)
vector<list>v;
for (int i = firs; i != -1; i = l[i].next) {
v.push_back(l[i]);
}
int len = v.size();
分组反转(address和data绑定,next需要改变)
int group = len / k;
//例子:len =10,k=4group=10/4=2组 0 1 2 3 4 56 7 8 9
for (int i = 0, j=0; j < group; i = i + k,j++ ) {
reverse(v.begin() + i, v.begin() + k + i);
cout << i << endl;
}
//修改next
for (int i = 0; i < len - 1; i++) {
v[i].next = v[i + 1].address;
}
v[len - 1].next = -1;
for (int i = 0; i < len - 1; i++) {
printf("%05d %d %05d\n", v[i].address, v[i].data, v[i].next);
}
printf("%05d %d %d\n", v[len - 1].address, v[len - 1].data, v[len - 1].next);
}
三、分析
1.读题分析:
address和next为地址,不重复
反转函数:reverse()
满足K个反转,不满足不反转,分组,L.size()/K除以取商
输入格式中节点地址,五位非负整数,NULL为-1,第一行为首节点
2.节点改变
注意next节点的改变,address和data绑定,一一对应,但是next节点会根据正序和逆序改变
3.测试点1
可能第二组反转出错
测试用例:
00000 5 2
00003 3 00004
00002 2 00003
00000 1 00002
00005 5 -1
00004 4 00005
正确:
代码:
分组反转(address和data绑定,next需要改变)
int group = len / k;
//len =10,k=4group=10/4=2组 0 1 2 3 4 56 7 8 9
for (int i = 0, j=0; j < group; i = i + k,j++ ) {
reverse(v.begin() + i, v.begin() + k + i);
cout << i << endl;
}
一直确定不了循环条件,干脆加了一个j用来判断,循环一次++,可以参考一下思路,单独创建一个判断条件
4.测试点5
运行超时,将cout换成printf试试
5.测试点6
输入的你个节点中,出现没有进入链中的节点。
例:有三个节点为a. 00100 4 00200 b.00200 6 -1 c.06544 8 23654
abc三个节点中,只有a.b链接,c为单独的无效/游离节点,所以计算循环次数时不用n/k
6.反思(默默叨叨):
感觉好多坑,花了好长时间,刚开始想用list发现不行,之后在纠结地址的类型string还是int,因为输出有00000,还在纠结struct常见出来的有没有next的记录,反正感觉好难(莫名其妙想用map那些),试了不行之后上网看代码,看思路 才一步一步做出来,这次注释比较多,都分段了,好定位。