原始想法
既然给定的序列是乱序的;
但是输出要求顺序,再按块反转输出
那么我为何不直接在读入的时候调整为顺序呢!
具体思路
- 读入1个结点后,剩下的结点,仅存在以下3种情况
插在他前面;插在他后面;直接空置(放到另一个容器a里) - 由于存在空置,因此当输入最后一个时,对容器a进行遍历,再次插入,直到符合题意的首尾
- 通过reverse进行块反转
- 输出时第一个是特殊的,中间是有一定规律的,最后补上-1
代码
#include<bits/stdc++.h>
using namespace std;
typedef struct node {
string address, next;
int key;
}node;
string start;
string tail{ "-1" };
int quantity = 0, group = 0;
void Insert(int i, node* w, deque<node*>& o, vector<node*>& t);
int main() {
cin >> start;
scanf("%d %d", &quantity, &group);
deque<node*> order;
vector<node*> temp;
for (int i = 0; i < quantity; i++) {
node* w = new node;
cin >> w->address >> w->key >> w->next;
Insert(i, w, order, temp);
}
for (int i = group; i <= order.size(); i += group) {
reverse(order.begin() + i - group, order.begin() + i);
}
for (auto i = order.begin(); i != order.end(); i++) {
if (i == order.begin()) {//修正首
cout << (*i)->address << " " << (*i)->key << " ";
}
else {
cout << (*i)->address << "\n" << (*i)->address << " " << (*i)->key << " ";
}
}
cout << "-1";
return 0;
}
void Insert(int i, node* w, deque<node*>& o, vector<node*>& t) {
if (!i) {
o.push_back(w);
return;
}
if (o.back()->next == w->address) {
o.push_back(w);
}
else if (o.front()->address == w->next) {
o.push_front(w);
}
else {
t.push_back(w);
}
if (i == quantity - 1) {
while (o.back()->next != tail || o.front()->address != start) {
vector<node*>::iterator j = t.begin();
for (; j != t.end(); j++) {
if (o.back()->next == (*j)->address) {
o.push_back(*j);
}
else if (o.front()->address == (*j)->next) {
o.push_front(*j);
}
}
}
}
}
优缺点
柳神代码的地址:https://www.liuchuo.net/archives/1910
对比柳神最大边界
在空间上占用较大,时间相较柳神的会短10ms左右
猜测原因:
- 效率高纯粹是双端队列头尾插入非常迅速
- 开了2个vector,由于vector不能进行动态变化,因此占用了2倍空间
- 同时采取string,空间占据也会更大一些
- next同时包含在数据结构内,也是占用了空间的,可能用map空间效率会更高,但写起来可能相对繁琐
彩蛋——测试点推测
测试点4为最小边界
测试点5为最大边界
测试点6有废点