目录
1,小红的大小写字母
大概题意是小红拿到了一个由大小写字母构成的长度为 N 的字符串,他每次操作可以将一个字符在大小写之间交换。
小红希望恰好 K 次操作后,大写字母的数量尽可能的多。
求最终字符串中大写字符的数量。
1 ≤ N ≤ 10^5, 1 ≤ K ≤ 10^9
输入示例:
1 3
A
输出结果:
0
输入示例:
5 3
arBrg
输出结果:
4
C++题解代码:
#include <bits/stdc++.h>
using namespace std;
#define endl '\\n'
#define int long long
void solve() {
int n, k;
cin >> n >> k;
string s;
cin >> s;
int res = 0;
// num1,num2分别表示字符串中小写字母,大写字母的数量
int num1 = 0, num2 = 0;
for (int i = 0; i < s.size(); i++) {
char c = s[i];
if (c >= 'a' && c <= 'z') {
num1++;
}
if (c >= 'A' && c <= 'Z') {
num2++;
}
}
// 如果小写字母小于操作次数,则把k个小写字母转化成大写字母
if (num1 >= k) {
res += k + num2;
} else { // num1 < k 反之,先把所有的小写字母转化成大写字母
res += n;
k -= num1; // 剩下操作次数:k - num1
// 把剩下操作,对一个字符单独操作,如果(k - num1)为偶数,操作后仍为大写的
// 否则变为小写,最终结果 - 1
if (k % 2 != 0) {
res--;
}
}
cout << res << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _ = 1;
//cin >> _;
while (_--) {
solve();
}
return 0;
}
2,锁
大概题意是牛牛有 n 份资源,初始化均处于未上锁状态。
现有 m 次操作,每次给定一个编号 p:
若编号为 p 的资源未上锁,则为其上锁。
否则,解锁;
每次操作后,牛牛希望分别统计区间 [ 1 , x ] 与 [ y , n ] 中可以*访问的资源(未上锁的资源)*的数量。
首先有多组测试数据,第一行输入 T ( 1 ≤ T ≤ 10^3 )代表数据组数。
每组测试数据有:
第一行四个整数,分别为 n , m , x , y ;
( 1 ≤ n ≤ 2 x 10^5 )( 1 ≤ m ≤ 4 x 10^5 )( 1 ≤ x ≤ n )( 1 ≤ y ≤ n )
输入示例:
2
4 3 2 3
2
3
3
6 6 4 2
1
3
6
4
4
2
输出结果:
1 2
1 1
1 2
3 5
2 4
2 3
1 2
2 3
1 2
C++代码题解:
#include <bits/stdc++.h>
using namespace std;
#define endl '\\n'
#define int long long
void solve() {
int n, m, x, y;
cin >> n >> m >> x >> y;
map<int, int> p;
// res1,res2分别表示[1,x],[y,n]区间可以访问的资源数
int res1 = x , res2 = n - y + 1; // 初始化(均可访问)
for (int i = 0; i < m; i++) {
int t;
cin >> t;
p[t]++; // 标记1: 不可访问(被上锁了) ; 标记0:可访问
if (p[t] == 2) p[t] = 0; // 有两次对同一数据操作,标记归零
if (t >= 1 && t <= x) {
if (p[t] == 1) // 标记为 1 编号为 t 的资源被上锁了
res1--;
else // 反之,编号为 t 的资源又被解锁了
res1++;
}
if (t >= y && t <= n) {
if (p[t] == 1) // 同上
res2--;
else
res2++;
}
cout << res1 << ' ' << res2 << endl;
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _ = 1; // 有多组测试数据
cin >> _;
while (_--) {
solve();
}
return 0;
}
3,牛牛的括号式
大概题意是牛牛给出了一个关于未知量 x 的多项式。这个多项式以字符串的形式表示,它是由若干个形如 ( x - d ) 或 ( x + d ) 的括号表达式相乘构成。其中 d 是一个1到9的数字字符。
牛牛想知道,这个多项式完全展开后,x 的一次项的系数是多少。
结果可能过大,对结果取模(10007)。
输入示例:
(x+1)(x+2)
输出结果:
3
C++代码题解:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 10007;
int a[100010]; // 存 -d 或 +d 的值,按顺序存
void solve() {
string s;
cin >> s;
// 特殊示例(只有一个式子)如 (x+1)
if (s.size() == 5) {
cout << 1 << endl;
return;
}
int len = 1;
// 取 -d 或 +d 的值
for (int i = 0; i < s.size(); i += 5) {
a[len] = s[i + 3] - '0';
if(s[i + 2] == '-') {
a[len] *= -1;
}
len++;
}
// 预处理
for (int i = 1; i < len; i++) {
a[i] = (a[i] % mod + mod) % mod; // 处理负数,确保结果非负
}
// 以下是使用递推方式,求 X^1 的系数,其实还可以推导多项式系数公式
int t1 = (a[1] + a[2]) % mod, t2 = (a[1] * a[2]) % mod;
for (int i = 3; i < len; i++) {
t1 = ((t1 * a[i]) % mod + t2) % mod;
t2 = (t2 * a[i]) % mod;
}
cout << t1 % mod << endl;
// 多项式 (x + a₁)(x + a₂)...(x + aₙ) 展开后,x^(n-1) 项的系数就是这个总和(初等对称多项式的第 n-1 项)。
// 超时,可以通过逆元优化
// int sum = 0;
// for (int i = 1; i < len; i++) {
// int res = 1;
// for (int j = 1; j < len; j++) {
// if (j != i) res = res * a[j] % mod;
// }
// sum += res % mod;
// }
// cout << sum % mod << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _ = 1;
// cin >> _;
while (_--) {
solve();
}
return 0;
}
4,题目忘了
区间查询问题:预处理数据后,对每个查询x,返回满足a≤x的最大b值。使用排序优化查询效率。
C++代码题解:
#include <bits/stdc++.h>
using namespace std;
#define endl '\\n'
#define int long long
pair<int, int> p[100010];
void solve() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
int a, b;
cin >> a >> b;
p[i].first = b;
p[i].second = a;
}
sort(p, p + n);
int q;
cin >> q;
while (q--) {
int x;
cin >> x; // a <= x
bool f = false;
for (int i = n - 1; i >= 0; i--) {
if (p[i].second <= x) {
cout << p[i].first << endl;
f = true;
break;
}
}
if (!f) cout << -1 << endl;
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _ = 1;
// cin >> _;
while (_--) {
solve();
}
return 0;
}
5,赛后AI所解
字符串子串统计问题:计算不含"d"且至少包含一个"e"和一个"r"的子串数量。采用容斥原理分块处理字符串。
是否正确不确定
AI代码:
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
void solve() {
string s;
cin >> s;
int res = 0;
int n = s.size();
int start = 0;
// 按'd'分割字符串,处理每个不含'd'的子段
while (start < n) {
// 跳过所有'd',找到子段起始
while (start < n && s[start] == 'd') start++;
if (start >= n) break;
// 找到当前子段的结束位置(下一个'd'或字符串末尾)
int end = start;
while (end < n && s[end] != 'd') end++;
// 提取当前子段(也可直接遍历,避免substr开销)
int m = end - start;
int total = m * (m + 1) / 2; // 该子段总子串数
// 计算不含'e'的子串数
int no_e = 0, cnt = 0;
for (int i = start; i < end; i++) {
if (s[i] != 'e') cnt++;
else {
no_e += cnt * (cnt + 1) / 2;
cnt = 0;
}
}
no_e += cnt * (cnt + 1) / 2;
// 计算不含'r'的子串数
int no_r = 0; cnt = 0;
for (int i = start; i < end; i++) {
if (s[i] != 'r') cnt++;
else {
no_r += cnt * (cnt + 1) / 2;
cnt = 0;
}
}
no_r += cnt * (cnt + 1) / 2;
// 计算既不含'e'也不含'r'的子串数
int no_e_r = 0; cnt = 0;
for (int i = start; i < end; i++) {
if (s[i] != 'e' && s[i] != 'r') cnt++;
else {
no_e_r += cnt * (cnt + 1) / 2;
cnt = 0;
}
}
no_e_r += cnt * (cnt + 1) / 2;
// 容斥原理:有效子串数 = 总 - 不含e - 不含r + 既不含e也不含r
res += (total - no_e - no_r + no_e_r);
// 移动到下一个子段起始
start = end;
}
cout << res << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _ = 1;
// cin >> _;
while (_--) {
solve();
}
return 0;
}
3584

被折叠的 条评论
为什么被折叠?



