c ++零基础可视化------vector
初始化
c
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进行初始化。
赋值运算,比较运算
c
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()
以下示例仅代表用法,并不是对同一数组进行连续操作,而代表的是每次都对最上面的数组进行操作,即不考虑之前对数组操作的语句对数组的改变。以此来演示语法规则。
c
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
c
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
c
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
c
#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
c
#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
c
#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, T;
cin >> n >> T;
vector<int> nums(n);
vector<int> newNums;
for(auto& x : nums) {
cin >> x;
}
while(T --) {
int k;
cin >> k;
for(int i = 0; i < k; i ++) {
for(int j = i; j < n; j += k) {
newNums.push_back(nums[j]);
}
}
nums = newNums;
newNums.clear();
}
for(auto& x : nums) {
cout << x << " ";
}
return 0;
}
启发:每次选人相当于分成k组。比如:当k = 2时,就会先选出索引为0 2 4 6 8...的人,再选出1 3 5 7 9...的人,先选出来的排在前面,后选出的排在后面。对题面的理解:每次选出的人都应该在第一个人的索引上加上k的倍数。
每次排出新的队伍,就保存在newNums中,再将新队伍newNums赋值给nums,最后将newNums清空。
要加深对数学型题面的理解。本题面加深了我的理解力。
问题四:https://www.luogu.com.cn/problem/B3745
c
#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, m, r;
cin >> n >> m >> r;
vector<int> f1(n), p1(n), f2(n), p2(n);
for(auto& x : f1) cin >> x;
for(auto& x : p1) cin >> x;
for(auto& x : f2) cin >> x;
for(auto& x : p2) cin >> x;
while(n --) {
int order;
cin >> order;
order --;
int idx = -1;
for(int i = 0; i < f2.size(); i ++) {
if(f2[i] == f1[order] && p2[i] > p1[order]) {
if(idx == -1 || p2[i] < p2[idx]) {
idx = i;
}
}
}
if(idx != -1) {
f2.erase(f2.begin() + idx);
p2.erase(p2.begin() + idx);
}
}
cout << f2.size() << endl;
return 0;
}
c
#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, m, r;
cin >> n >> m >> r;
vector<int> p1(n), f1(n), p2(n), f2(n);
vector<int> output(n);
for(int i = 0; i < n; i ++) {
cin >> f1[i];
}
for(int i = 0; i < n; i ++) {
cin >> p1[i];
}
for(int i = 0; i < n; i ++) {
cin >> f2[i];
}
for(int i = 0; i < n; i ++) {
cin >> p2[i];
}
for(int i = 0; i < n; i ++) {
cin >> output[i];
}
int cnt = 0;
for(int i = 0; i < n; i ++) {
int outF = f1[output[i] - 1], outP = p1[output[i] - 1];
vector<pair<int, int>> temp;
for(int j = 0; j < n; j ++) {
if(f2[j] == outF && f2[j] != -1 && p2[j] > outP) {
temp.push_back({f2[j], p2[j]}); // F P
}
}
int maxMin = 101;
for(auto& x : temp) {
if(x.second > outP && x.second < maxMin) {
maxMin = x.second;
}
}
if(maxMin != 101) {
for(auto& x : temp) {
if(x.second == maxMin) {
for(int k = 0; k < n; k ++) {
if(f2[k] == x.first && p2[k] == x.second) {
f2[k] = p2[k] = -1;
break;
}
}
break;
}
}
cnt ++;
}
temp.clear();
}
cout << n - cnt << endl;
return 0;
}
启发:模拟题,题目不难,显然上面的代码精简。但我的方法很冗长复杂,究其原因还是没有熟练掌握vector的精髓之处。我与其对比,纵观我的代码,我总是想要存储数据,但这完全不必要。而且应用的函数也很少,总是用push_back()
。这导致我的方法不够好。