c ++零基础可视化——vector
初始化
vector<int> v0(5); // 0 0 0 0 0
vector<int> v1(5, 1); // 1 1 1 1 1
vector<int> v2{1, 2, 3} // 1 2 3
vector<int> v3(v1); // 1 1 1 1 1
vector<vector<int>> v4(2, vector<int>(8, 3));
// 3 3 3 3 3 3 3 3
// 3 3 3 3 3 3 3 3
auto v5 = vector(2, vector<int>(8, 3));
// 3 3 3 3 3 3 3 3
// 3 3 3 3 3 3 3 3
启发:使用auto可以更好对二位vector进行初始化。
赋值运算,比较运算
vector<int> v0{1, 2, 3};
vector<int> v1;
v1 = v0;
vector<int> v2{1, 2, 4};
v0 < v2;
比较大小:按字典序比较。
vector常用成员函数
v.front()
获取vector的第一个元素
v.back()
获取vector的最后一个元素
v.size()
获取vector的元素个数
v.empty()
判断vector是否为空
v.clear()
清空vector的数据
v.push_back()
将数据塞入vector的末尾
v.pop_back()
将数据从vector的末尾移除
v.resize(3)
重新定义vector的大小。若比原先小,则删除末尾元素;若比原先大,则用0填充新增的元素;v.resize(5, 1)
若有第二个参数,则用第二个参数来填充
v.begin()
v.end()
以下示例仅代表用法,并不是对同一数组进行连续操作,而代表的是每次都对最上面的数组进行操作,即不考虑之前对数组操作的语句对数组的改变。以此来演示语法规则。
vector<int> v{1, 2, 3, 4, 5};
v.erase(v.begin()); //删除1,得到2 3 4 5
v.erase(v.begin() + 1, v.end() + 3) //删除2 3,得到1 4 5
vector<int> v{1, 2, 3};
v.insert(v.begin(), 4); //插入4,得到4 1 2 3
v.insert(v.begin + 1, {4, 5, 6}); //插入4 5 6,得到 1 4 5 6 2 3
vector<int> v1(1, 2, 3);
vector<int> v2(4, 5, 6);
v1.insert(v1.end(), v2.begin(), v2.end()); //插入 4 5 6,得到 1 2 3 4 5 6
题目一【旋转排列】:https://www.luogu.com.cn/problem/B3688
[语言月赛202212] 旋转排列
题目背景
我们称一个数列 p p p 是一个长度为 n n n 的排列,当且仅当 p p p 满足如下条件:
- p p p 的长度为 n n n;
- 1 , 2 , 3 , … n 1, 2, 3, \dots n 1,2,3,…n 这 n n n 个数在 p p p 中均恰好出现一次。
题目描述
对于一个排列 p p p,定义一次“shift”操作是指:将 p p p 里的每一个数字都依次向后移动一位,并把 p p p 的最后一个数字移动到开头去。
例如,若排列 p p p 初始时为 [ 1 , 4 , 2 , 3 ] [1,4,2,3] [1,4,2,3],则“shift”一次以后将变为 [ 3 , 1 , 4 , 2 ] [3,1,4,2] [3,1,4,2]。
现在,给定一个长度为 n n n 的排列 p p p,请你按照如下规定循环操作:
- 对当前的排列 p p p 做一次“shift”操作;
- 输出本次“shift”以后的排列 p p p;
- 判断排列 p p p 的最后一个数字是否是 n n n,如果是,则结束循环操作;否则回到 1 1 1 继续操作。
提示:请严格按照题目给出的顺序进行循环操作。
输入格式
第一行是一个整数,表示排列
p
p
p 的长度
n
n
n。
第二行有
n
n
n 个整数表示排列
p
p
p,第
i
i
i 个整数表示
p
i
p_i
pi。
输出格式
对于每次操作的第二条“输出”操作,请你输出一行 n n n 个整数,按顺序表示当前排列的每个数,一行中相邻两个数之间用一个空格隔开。
样例 #1
样例输入 #1
4
1 4 2 3
样例输出 #1
3 1 4 2
2 3 1 4
样例 #2
样例输入 #2
3
1 2 3
样例输出 #2
3 1 2
2 3 1
1 2 3
样例 #3
样例输入 #3
10
1 7 6 5 8 4 3 9 10 2
样例输出 #3
2 1 7 6 5 8 4 3 9 10
提示
样例 2 解释
对 p = [ 1 , 2 , 3 ] p = [1, 2, 3] p=[1,2,3],按如下顺序进行循环操作:
- 进行一次“shift”操作, p p p 变为 [ 3 , 1 , 2 ] [3,1,2] [3,1,2];
- 输出当前的排列
p
p
p,故输出第一行为
3 1 2
; - 判断 p 3 = 2 ≠ 3 p_3 = 2 \neq 3 p3=2=3,故继续循环操作;
- 进行一次“shift”操作, p p p 变为 [ 2 , 3 , 1 ] [2,3,1] [2,3,1];
- 输出当前的排列
p
p
p,故输出第二行为
2 3 1
; - 输出判断 p 3 = 1 ≠ 3 p_3 = 1 \neq 3 p3=1=3,故继续循环操作;
- 进行一次“shift”操作, p p p 变为 [ 1 , 2 , 3 ] [1,2,3] [1,2,3];
- 输出当前的排列
p
p
p,故输出第二行为
1 2 3
; - 输出判断 p 3 = 3 = 3 p_3 = 3 =3 p3=3=3,故停止循环;
数据规模与约定
各测试点的信息如下表:
测试点编号 | $n = $ | 特殊约定 |
---|---|---|
1 1 1 | 1 1 1 | 无 |
2 2 2 | 2 2 2 | 无 |
3 3 3 | 3 3 3 | 无 |
4 ∼ 6 4 \sim 6 4∼6 | 2000 2000 2000 | p n − 1 = n p_{n - 1} = n pn−1=n |
7 ∼ 10 7 \sim 10 7∼10 | 2000 2000 2000 | 无 |
对全部的测试点,保证 1 ≤ p i ≤ n ≤ 2000 1 \leq p_i \leq n \leq 2000 1≤pi≤n≤2000, p p p 是长度为 n n n 的排列。
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
#define endl "\n"
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> nums(n);
for(auto& x : nums) cin >> x;
do {
int back = nums.back();
nums.pop_back();
nums.insert(nums.begin(), back);
for(auto& x : nums) cout << x << " ";
cout << endl;
}while(nums.back() != n);
return 0;
}
启发:使用do while语句可以完美契合题意;注意精简代码。
问题二【进制转换】:https://www.luogu.com.cn/problem/B3849
[GESP样题 三级] 进制转换
题目描述
小美刚刚学习了十六进制,她觉得很有趣,想到是不是还有更大的进制呢?在十六进制中,用 A
表示
10
10
10、F
表示
15
15
15。如果扩展到用 Z
表示
35
35
35,岂不是可以表示
36
36
36 进制数了嘛!
所以,你需要帮助她写一个程序,完成十进制转 R R R 进制( 2 ≤ R ≤ 36 2\le R\le 36 2≤R≤36)的工作。
输入格式
输入两行,第一行包含一个正整数 N N N,第二行包含一个正整数 R R R,保证 1 ≤ N ≤ 1 0 6 1\le N\le 10^6 1≤N≤106。
输出格式
输出一行,为 N N N 的 R R R 进制表示。
样例 #1
样例输入 #1
123
25
样例输出 #1
4N
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
#define endl "\n"
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, R;
cin >> n >> R;
vector<int> digit;
while(n) {
digit.push_back(n % R);
n /= R;
}
reverse(digit.begin(), digit.end());
for(auto& x : digit) {
if(x < 10) {
cout << x;
} else {
cout << char(x - 10 + 'A');
}
}
return 0;
}
启发:隐式转换;如何取出数字的每一位。
问题三【排排队,做游戏】:https://www.luogu.com.cn/problem/B3766
[语言月赛202305] 排排队,做游戏
题目描述
n n n 名小朋友站成了一排,他们会按照体育老师的指令进行排队做游戏。
体育老师会向他们依次下发 T T T 条指令,每条指令包含一个小于等于 n n n 的正整数 k k k。
对某一条指令,小朋友们会按照如下步骤进行排队:
- 该指令下发前,排在从左到右数第