RE:从零开始的算法之路第一章

0.关于

STL(StandardTemplateLibrary)是C艹的标准模板库,包含容器,迭代器,配接器,算法,仿函数,空间适配器6个方面组成,第一章只有容器和一个常用算法
容器使用时要#include<容器名称>(优先队列只需要队列)

1.vector

介绍

数组是高级语言基本的数据结构,但C艹的静态数组不能根据需要扩大或缩小空间,虽然能定义足够大,但在空间紧张或需要少量增删是可以利用动态数组的方法更简单的实现.
由于vector本质还是数组,内存空间是连续的,所以增删回造成内存块的复制,所以并不适合大量增删
更多关于vector

定义

  1. 基本定义
    vector<类型>命名(初始化元素数量,初始化元素);可自己选择如何初始化,给一个参数默认是数量
   vector<int>a(100);// 定义一个int类型的a,并初始化100个元素,未指定时int类型默认0,所以a有100个0元素
   vector<string>b(10,"hello");//定义一个string类型的b,并初始化10个元素"hello" 
  1. 复制定义
   vector<int>b(a);//用a来定义b,基本等同于复制
   vector<string>c(b.begin(),b.end());//c是b的复制,begin和end是迭代器.相当于能遍历的头指针和尾指针
  1. 结构体定义
struct point{
   
int x,y;
};
vector<point>p;//定义一个存x,y的point类型的动态数组p
  1. 套娃定义
vector<int>a[10];//a是有10个元素的数组,每个元素又是一个动态数组,类似于二维数组
vector<int>one;
vector<one>two;//套娃起来了

常用操作(标记的表示stl通用)

vector< int >a;

  1. 增加
  • a.push_back(元素数量, 元素);向尾部插入一个元素,或插入规定数量相同元素
  • a.insert(下标位置,元素数量, 元素);在下标位置插入一个元素,或插入规定数量相同元素,下标位置由迭代器begin,end控制
a.push_back(114514);//在a尾部插入114514这个数
a.insert(a.begin()+i,n);//将n插在第i下标处
a.insert(a.end(),114,514);//在a最后插入114个514
  1. 删除
  • a.pop_back();删除末尾元素
  • a.erase(开始位置,结束位置 );包含开始位置不包含结束位置,可以只有开始位置只删一位
  • a.clear();清空a中所有元素,栈和队列不能用这个函数
a.pop_back(7);//删除a中末尾元素
a.erase(a.begin()+i,a.begin()+n);//删除[i,n)所有元素
a.erase(a.begin()+i);//删除下标为i的元素

3.其他

  • a.size();//a中元素个数
  • a.empty();//a是否为空,返回一个bool类型来判断
  • a.resize(n);//将a数值大小变为n
  • reverse(开始位置,结束位置);//将开始位置到结束位置翻转
  • sort(开始位置,结束位置,排序方法);//将开始位置到结束位置排序,方法可不写,默认升序

例题

  • 圆桌问题 HDU 4841
    Problem Description
    圆桌上围坐着2n个人。其中n个人是好人,另外n个人是坏人。如果从第一个人开始数数,数到第m个人,则立即处死该人;然后从被处死的人之后开始数数,再将数到的第m个人处死……依此方法不断处死围坐在圆桌上的人。试问预先应如何安排这些好人与坏人的座位,能使得在处死n个人之后,圆桌上围坐的剩余的n个人全是好人。

  • Input
    多组数据,每组数据输入:好人和坏人的人数n(<=32767)、步长m(<=32767);

  • Output
    对于每一组数据,输出2n个大写字母,‘G’表示好人,‘B’表示坏人,50个字母为一行,不允许出现空白字符。相邻数据间留有一空行。

  • Sample Input
    2 3
    2 4

  • Sample Output
    GBBG
    BGGB

思路:
如想用静态数组,则设置一个足够大的数组初始化全为0,将0代表好人,则需要将一半的人也就是n个人转化成1就可以了.

  • 转化过程需要一个数去记1的数目到n就结束
  • 需要一个计步器走一步加1,到3置0且在跳1时不加
  • 需要将总步数求余来循环

但如果用静态数组做的话,由于数组的大小不变,每次遍历都要遍历全部,时间耗费更多容易导致超时(但不是不行)
在这里插入图片描述

代码:

#include<iostream>
#include <algorithm>
#include<string.h>
#include<vector>
const int maxn = 1e5 + 10;
#define re(x) for(int i=0;i<x;++i)
#define rey(x) for(int j=0;j<x;++j)//可以用简单的写法使用循环
typedef long long LL;
using namespace std;
int T, n, a[maxn], m,p;
int main()
{
   
	ios::sync_with_stdio(0); cin.tie(0);
	vector<int>table;//定义int型的table
	while (cin>>n,cin>>m)
	{
   
		table.clear();//为了下一次循环而清零
		re(2 * n)table.push_back(i);//将table里存入0~2n-1
		p = 0;//跳的位置
		re(n) {
   
			p = (p + m -1) % table.size();//取余来保证p不超过table.size()
			table.erase(table.begin() + p);//每m人就将其元素删除
		}
		T = 0;
		re(2 * n) {
   
			if (!(i % 50) && i
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值