P1188 PASTE
这道题可以直接用链表来做
注:这篇题解中的链表是用指针实现的,理解起来可能比较有难度。
题意简述
这道题会给出
题面不难理解,只需要注意插入的位置是在取出要剪切的的那一段之后的位置。
题目分析
链表插入和删除都非常快,查询链表中某一元素位置的平均复杂度为
我们首先找到第
需要注意的是,由于存在插入到第
定义一个元素结构体,构造函数等已略去。
template <typename T>
struct element{
T object;
element<T> *prev;
element<T> *next;
};
之后我们需要给出双向链表的实现,具体代码请看完整代码部分,这里给出最核心的剪贴代码。其中ch为我们定义的链表类型的变量,getPointer()为获取某一个元素的指针的函数。
for(int i = 1; i <= m; i++) {
int l, r, p; // 分别代表输入的A B C
scanf("%d%d%d", &l, &r, &p);
element<int> *pl, *pr, *pp;
pl = ch.getPointer(l);
pr = ch.getPointer(r);
// 获取要剪切的两端的指针
pl->prev->next = pr->next;
pr->next->prev = pl->prev;
// 从链表中删除
pp = ch.getPointer(p);
pl->prev = pp;
pr->next = pp->next;
pp->next->prev = pr;
pp->next = pl;
// 将剪切出来的那一段插入到c行后面
}
完整代码
/* Headers */
#include <cstdio>
#include <iostream>
using namespace std;
/* Type and variables */
int n, m;
template <typename T>
struct element{
T object;
element<T> *prev;
element<T> *next;
element() {f
object = 0;
}
element(T value) {
object = value;
}
element(T value, element<T>* prev, element<T>* next) {
object = value;
this->prev = prev;
this->next = next;
}
};
template <typename T> // 模板类
class chain{
int eleCount; // 已有元素数量
element<T> *head;
element<T> *tail;
public:
chain(){ // 链表的构造函数,首先构造一个头部元素
eleCount = 0;
head = new element<T>(0);
tail = head;
head->prev = head;
head->next = head;
}
element<T>* getPointer(int pos) { // 获取排列在第pos位的元素的指针
element<T> *p = head;
for(int i = 1; i <= pos; i++) {
p = p->next;
}
return p;
}
void addElement(T value) { // 在尾部添加一个元素
eleCount++;
element<T> *p = new element<T>(value, tail, tail->next);
p->prev->next = p;
p->next->prev = p;
tail = p;
}
void print(int c) { // 输出链表中除头部元素外的前c个元素
element<T> *p = head;
for(int i = 1; i <= c; i++) {
p = p->next;
cout << p->object;
putchar('\n');
}
}
};
chain<int> ch = chain<int>();
/* Functions */
/* Main */
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
ch.addElement(i);
for(int i = 1; i <= m; i++) {
int l, r, p;
scanf("%d%d%d", &l, &r, &p);
element<int> *pl, *pr, *pp;
pl = ch.getPointer(l);
pr = ch.getPointer(r);
// 获取这一段两边的指针
pl->prev->next = pr->next;
pr->next->prev = pl->prev;
// 将这一段从链表中移除
pp = ch.getPointer(p);
// 获取移除后要粘贴的位置的指针
pl->prev = pp;
pr->next = pp->next;
pp->next->prev = pr;
pp->next = pl;
// 再把这一段插入到要粘贴的位置后面
}
ch.print(10); // 最后输出即可 >w<
return 0;
}
227ms