A题
Problem A. 字符串
数据库是结构化信息或数据(一般以电子形式存储在计算机系统中)的有组织的集合,通常由数据库管 理系统 (DBMS) 来控制。在现实中,数据、 DBMS 及关联应用一起被称为数据库系统,通常简称为数据 库。 为了提高数据处理和查询效率,当今最常见的数据库通常以行和列的形式将数据存储在一系列的表中, 支持用户便捷地访问、管理、修改、更新、控制和组织数据。另外,大多数数据库都使用结构化查询语言 (SQL) 来编写和查询数据。 接下来给你一个长度为 n 的字符串,对字符串进行 q 次查询,每次查询会输入一个操作数 \1. x:删除字符串中所有 ASCII 码等于 x 的字符。 \2. p:添加一个 ASCII 码等于 p 的字符。 \3. 按照字典序输出该字符串。 Input 第一行输入一个整数 n,表示字符串 S 的长度 接下来输字符串 S (n ≤ 2e5) 第三行输入操作次数 q (q ≤ 1000) 接下来 q 行输入每种操作 Output 按题目描述输出即可 Examples
/* 9 abcccbaaa 3 1 98 2 10 1 3 */ // aaaaccce
Explanations 字典序是指按照单词出现在字典的顺序进行排序的方法。——维基百科
分析:vector容器的基本删除和遍历操作;
1.已知字符串长度,则直接循环读入即可
2.根据题目对vector进行操作即可;
#include<bits/stdc++.h> #define endl '\n' #define int long long int n; char x; using namespace std; vector<char> a; signed main() { cin.tie(0)->ios::sync_with_stdio(false); cin>>n; while(n--) { cin>>x; a.push_back(x); } int q; cin>>q; while(q--) { int n; cin>>n; if(n==1) { int m; cin>>m; //寻找,且删除 for(auto it=a.begin();it!=a.end();it++) { if(*it==m) { it=a.erase(it); it--; } } } if(n==2) { int m; cin>>m; //加入 a.push_back(m); } if(n==3) {//排序并遍历输出 sort(a.begin(),a.end()); for(auto it=a.begin();it!=a.end();it++) cout<<*it; cout<<endl; } } }
B题
分析:
异或运算即:二进制位数上的数字相同则为0,不同则为1;
由样例可知:
2 2 1 3 1 2 4 1
序列长度为4,两次操作,
第一次操作:位置1和3异或结果为1,则1和3位置,其中一个为1,其中一个为0;
第二次操作:位置2和4异或结果也为1,则2和4位置,其中一个为1,其中一个为0;
所以该序列元素和1+0+0+1=2;
即假设:如果两个位置异或结果0,则两个位置都为0或者1,由于求得是序列中所有元素最小和,所以两个位置的和当作0即可;
所以把每次操作的异或结果相加即是答案
#include <bits/stdc++.h> #define endl '\n' using namespace std; #define int long long signed main() { cin.tie(0)->ios::sync_with_stdio(false); int n, q, ans(0); cin >> n >> q; for (int i = 1; i <= q; i++) { int u, v, w; cin >> u >> v >> w; ans += w; } cout << ans << endl; return 0; }
C题
分析:
1.需要一个结构体存每一次操作的坐标,用于定位小矩形;struct f{int a,int b,int c,int d};
2.需要一个求和函数,用于分别求小矩形的大小;int solve()
3.需要一个数存原始矩形:a[i] [j];
4.需要一个数组表示矩阵的增加值b[i] [j];(差分矩阵)时间复杂度O(1)
差分矩阵
朴素版实现O(n*n)
:
for(int i=x1;i<x2;++i){ for(int j=y1;i<=y2;++j{ a[i][i]+=c; } }
差分矩阵核心操作O(1)
//差分矩阵最核心的操作 static void insert(int x1,int y1,int x2,int y2,int c){ s[x1][y1]+=c; s[x1][y2+1]-=c; s[x2+1][y1]-=c; s[x2+1][y2+1]+=c; }
#include <bits/stdc++.h> #define endl '\n' #define int long long using namespace std; const int N = 1005 + 10; int a[N][N], n, m, b[N][N], q, c[N][N]; struct f { int a, b, c, d; } qu[N]; int solve(int q, int w, int e, int r) { return c[e][r] - c[q - 1][r] - c[e][w - 1] + c[q - 1][w - 1]; } signed main() { cin.tie(0)->ios::sync_with_stdio(false); cin >> n >> m; //读入原始矩阵 for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> a[i][j]; } } int q; cin >> q;//读入操作次数; for (int i = 1; i <= q; i++) { int x1, y1, x2, y2, p; cin >> x1 >> y1 >> x2 >> y2 >> p; qu[i].a = x1; qu[i].b = y1; qu[i].c = x2; qu[i].d = y2; //差分矩阵 b[x1][y1] += p; b[x1][y2 + 1] += -p; b[x2 + 1][y1] += -p; b[x2 + 1][y2 + 1] += p; } int sum(0);//结果 //二位前缀和的操作 for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1]; a[i][j] += b[i][j]; c[i][j] = c[i - 1][j] + c[i][j - 1] - c[i - 1][j - 1] + a[i][j]; } } for (int i = 1; i <= q; i++) { sum = max(sum, solve(qu[i].a, qu[i].b, qu[i].c, qu[i].d)); } cout << sum << endl; return 0; }
前三题解题报告,后面的解题报告不想写了,还有数学和英语作业没写。
关于我的学习方法:看视频50%,刷题50% 主要是自己在哔哩哔哩上寻找一些视频自学,还有就是在CSDN上看文章自学。 题目主要是写文章或者视频里的题目; 自己先把题读一遍,然后在心中模拟一下这题该怎么解,用什么容器,用什么算法,需要开什么函数; 然后再听讲解。
也没有特别的学习方法,主要是需要付出努力!