2019牛客国庆集训派对 双向链表练习题 解题报告
双向链表练习题
https://ac.nowcoder.com/acm/contest/1099/K
链接
解题思路
这是一道模拟题。要求不断地让一个列表追加到另一个列表中,并反转。但是不停反转是很耗性能的,不停地反转将会导致超时。为了解决这个反转超时问题,我们开两个表,一个正向表,一个反向表。把正向表与反向表的元素对调一下,就相当于反转了。这样就不会超时了。
+-----------+
| 开始 |
+-----------+
|
|
|
|
v
+---------------------------------+
| 建两个链表,一个正向表,一个反向表 |
+---------------------------------+
|
|<-------------------------------+
| |
v |
+-------------+ |
| 输入追加操作 | |
+-------------+ |
| |
| |
| |
v |
+------------------------+ |
| 对正向表执行追加操作,即 | |
| 正向表La += Lb | |
+------------------------+ |
| |
| |
| |
v |
+---------------------------------+ |
| 对反向表倒过来执行逆向追加操作,即 | |
| 反向表Lb += La | |
+---------------------------------+ |
| |
| |
| |
v |
+-------------------------------------+ |
| 把这两个表的刚变的两个元素对调一下,即 | |
| swap(正La, 反Lb) | |
+-------------------------------------+ |
| |
| |
v |
+-------------------------------+ |
| 把反向表的元素放到正确的位置,即 | |
| swap(反La, 反Lb) | |
+-------------------------------+ |
| |
| |
| |
v |
X |
X XXX |
XXX XXX |
XXXX XXXX 有 |
XXXX 还有下个操作吗? XX+------------------+
XX XXX
XX XXX XX
XXXXXX XX
XXXX X X
XX
|
| 无
|
v
+-------------------+
| |
| 输出正向表的L1元素 |
| |
+-------------------+
|
|
|
|
|
v
+---------+
| 结束 |
+---------+源代码
#include <cstdio>
#include <list>
#include <algorithm>
using namespace std;
#define MAX_LENGTH 100001
int main()
{
int n, m;
static list<int> plist[MAX_LENGTH];
static list<int> plist_reverse[MAX_LENGTH];
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = 1; i <= n; ++i)
{
plist[i].clear();
plist[i].push_back(i);
plist_reverse[i].clear();
plist_reverse[i].push_back(i);
}
while (m --)
{
int a, b;
scanf("%d%d", &a, &b);
plist[a].splice(plist[a].end(), plist[b]);
plist_reverse[b].splice(plist_reverse[b].end(), plist_reverse[a]);
swap(plist[a], plist_reverse[b]);
swap(plist_reverse[a], plist_reverse[b]);
}
printf("%d", (int)(plist[1].size()));
for (int e : plist[1])
printf(" %d", e);
puts("");
}
return 0;
} 
查看24道真题和解析