代码源:57、序列维护

263 阅读3分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路 logo.png

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目描述

这是3月13日代码源div2的每日一题。

知识点:链表(STL)

序列维护 - 题目 - Daimayuan Online Judge

你有一个序列,现在你要支持几种操作:

  • insert x y,在从前往后的第x个元素后面插入y这个数。如果x=0,那么就在开头插入。
  • delete x,删除从前往后的第x个元素。
  • query k,询问从前往后数第k个元素是多少。

输入格式

第一行一个整数m,表示操作个数。

接下来m行,每行一个上面所述的操作。

输出格式

输出若干行,对于每个查询操作,输出答案。

样例输入

10
insert 0 1
insert 1 2
query 1
query 2
insert 0 3
query 1
delete 1
query 1
insert 1 4 
query 2

样例输出

1
2
3
1
4

数据规模

对于100%的数据,保证m≤10^3。

对于insert操作,保证1≤y≤10^9。

对于所有操作,保证位置不会超出当前序列的长度。

问题解析

这题我觉着就当练习stl了,当然不会stl的也可以用手写链表来写(我没写)。这里用的是stl中的list容器(用vector容器也是可以的,操作和list仅有迭代器的操作不同)。

先给没使用过list的同学讲下list:

使用时包含头文件#include < list>,创建格式:list<数据类型>名字,比如:list< int>l;

  • push_back(elem);——在容器尾部加入一个元素

  • pop_back();——删除容器中最后一个元素

  • push_front(elem);——在容器开头插入一个元素

  • pop_front();——从容器开头移除第一个元素

  • insert(pos,elem);——在pos位置插入elem元素的拷贝,返回新数据的位置

  • insert(pos,n,elem);——在pos位置插入n个elem数据,无返回值

  • insert(pos,beg,end);——在pos位置插入[beg,end)区间的数据,无返回值

  • clear();——移除容器的所有数据

  • erase(beg,end);——删除[beg,end)区间的数据,返回下一个数据的位置

  • erase(pos);——删除pos位置的数据,返回下一个数据的位置

  • remove(elem);——删除容器中所有与elem值匹配的元素

而这些所谓“位置“,靠的是stl里遍历容器时用到的一种类似指针的东西,名叫迭代器,一个容器的迭代器有begin()和end()两种,对应开头和结尾。就像指针遍历数组时,指针++会往下个位置走一样,迭代器也是通过++来往下个位置走。

基础的就讲这些,想学习stl的,推荐b站黑马程序员的c++课程。

AC代码

list写法

#include<iostream>
using namespace std;
#include<algorithm>
#include<list>

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    list<int>l;
    int n;
    cin >> n;
    while (n--)
    {
        string str;
        cin >> str;
        if (str == "insert")
        {
            int a, b;
            cin >> a >> b;
            auto it = l.begin();
            while (a--)it++;
            l.insert(it, b);
        }
        else if (str == "query")
        {
            int a;
            cin >> a;
            auto it = l.begin();
            while (--a)it++;
            cout << *it << '\n';
        }
        else
        {
            int a;
            auto it = l.begin();
            cin >> a;
            while (--a)it++;
            l.erase(it);
        }
    }
    return 0;
}

vector写法

#include<iostream>
#include<vector>
#include<string>
using namespace std;
vector<int> v;
int main()
{
	int m;
	cin >> m;
	while (m--) {
		string str;
		cin >> str;
		if (str == "insert") {
			int a, b;
			cin >> a >> b;
			auto ite = v.begin();
			while (a--)ite++;
			v.insert(ite, b);
		}
		else if (str == "query") {
			int a;
			cin >> a;
			auto ite = v.begin();
			while (--a)ite++;
			cout << *ite << '\n';
		}
		else if (str == "delete") {
			int a;
			cin >> a;
			auto ite = v.begin();
			while (--a)ite++;
			v.erase(ite);
		}
	}
	return 0;
}