前言
不会F,待补,如果有问题欢迎大家评论或私信指出
题解
A.小红的好数
判断一下字符串前两位是否相等即可
#include<bits/stdc++.h>
using i64 = long long;
void solve() {
std::string s;
std::cin >> s;
if (s[0] == s[1] && s.size() == 2) {
std::cout << "Yes" << '\n';
}
else {
std::cout << "No" << '\n';
}
}
signed main() {
std::ios::sync_with_stdio(0);
std::cout.tie(0);
std::cin.tie(0);
i64 t = 1;
// std::cin >> t;
while (t--) {
solve();
}
}
B.小红的好数组
暴力判断所有长度为k的子数组是否可以修改小于等于一个位置使其变成回文串
#include<bits/stdc++.h>
using i64 = long long;
void solve() {
int n, k;
std::cin >> n >> k;
std::vector<int> a(n + 1);
auto check = [&] (int l, int r) -> bool {
int res = 0;
while(l <= r) {
if (a[l] != a[r]) {
res++;
}
l++, r--;
}
if (res == 1) {
return true;
}
else {
return false;
}
};
int ans = 0;
for (int i = 1; i <= n; i++) {
std::cin >> a[i];
if (i >= k) {
if(check(i - k + 1, i)) {
ans++;
}
}
}
std::cout << ans << '\n';
}
signed main() {
std::ios::sync_with_stdio(0);
std::cout.tie(0);
std::cin.tie(0);
i64 t = 1;
// std::cin >> t;
while (t--) {
solve();
}
}
C.小红的矩阵行走
就bfs,但需要判断一下,下一步要走的地方如果和起始位置的值相同才能继续走。
#include<bits/stdc++.h>
using i64 = long long;
int dx[2] = {0, 1};
int dy[2] = {1 ,0};
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<std::vector<int> > mp(n + 1, std::vector<int> (m + 1));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
std::cin >> mp[i][j];
}
}
std::queue<std::tuple<int, int, int> > q;
q.push({1, 1, mp[1][1]});
while(!q.empty()) {
auto [x, y, v] = q.front();
q.pop();
if (x == n && y == m) {
std::cout << "Yes" << '\n';
return;
}
for (int i = 0; i < 2; i++) {
int xx = x + dx[i], yy = y + dy[i];
if (xx < 1 || xx > n || yy < 1 || yy > m) continue;
if (mp[xx][yy] != v) {
continue;
}
q.push({xx, yy, v});
}
}
std::cout << "No" << '\n';
}
signed main() {
std::ios::sync_with_stdio(0);
std::cout.tie(0);
std::cin.tie(0);
i64 t = 1;
std::cin >> t;
while (t--) {
solve();
}
}
D.小红的行列式构造
不会证明,我纯手玩模拟出来的规律。
#include<bits/stdc++.h>
using i64 = long long;
void solve() {
int x;
std::cin >> x;
if (x >= 0) {
std::cout << "1 1 1\n";
std::cout << "1 2 1\n";
std::cout << "1 1 " << x + 1 << '\n';
}
else {
std::cout << "-1 -1 -1\n";
std::cout << "-1 -2 -1\n";
std::cout << "-1 -1 " << x - 1 << '\n';
}
}
signed main() {
std::ios::sync_with_stdio(0);
std::cout.tie(0);
std::cin.tie(0);
i64 t = 1;
// std::cin >> t;
while (t--) {
solve();
}
}
E.小红的 red 计数
就考虑翻转某一段区间多了什么和少了什么,考虑red时如果ed都在区间内,那翻转时就会把red变成rde,同理,会吧rde变为red,如果re在区间内,那就会把red变换成erd,会把erd变换成red,如果red都在区间内就会把red变换der,把der变换成red。算出以上贡献即可。所以答案就是-区间前r的个数和区间内ed的乘积+区间前r和区间内de的乘积 - 区间内red的个数 + 区间内der的个数 - 区间内re和区间后d的个数的乘积 + 区间内er和区间后d个数的乘积。问题变成了,区间内re的个数要怎么算呢,就是到区间右端点内re的个数-到区间左端点内re的个数-区间前r的个数乘上区间内e的个数。自己再思考一下那区间内red的个数怎么求呢。代码仅供参考,维护前缀和的时候还打了遍差分。
#include<bits/stdc++.h>
using i64 = long long;
void solve() {
i64 n, q;
std::cin >> n >> q;
std::string s;
std::cin >> s;
s = ' ' + s;
//r, e, d, re, er, ed, de, red, der
std::vector<i64> prer(n + 1), pred(n + 1), pree(n + 1), prere(n + 1), preer(n + 1), preed(n + 1), prede(n + 1), prered(n + 1), preder(n + 1);
for (i64 i = 1; i <= n; i++) {
if (s[i] == 'r') {
prer[i] += 1;
preer[i] += pree[i - 1];
preder[i] += prede[i - 1];
}
else if (s[i] == 'e') {
pree[i] += 1;
prere[i] += prer[i - 1];
prede[i] += pred[i - 1];
}
else if (s[i] == 'd') {
pred[i] += 1;
preed[i] += pree[i - 1];
prered[i] += prere[i - 1];
}
prer[i] += prer[i - 1];
pree[i] += pree[i - 1];
pred[i] += pred[i - 1];
prere[i] += prere[i - 1];
preer[i] += preer[i - 1];
preed[i] += preed[i - 1];
prede[i] += prede[i - 1];
prered[i] += prered[i - 1];
preder[i] += preder[i - 1];
}
auto sumr = [&](i64 l, i64 r) -> i64 {
return prer[r] - prer[l - 1];
};
auto sume = [&](i64 l, i64 r) -> i64 {
return pree[r] - pree[l - 1];
};
auto sumd = [&](i64 l, i64 r) -> i64 {
return pred[r] - pred[l - 1];
};
auto sumre = [&](i64 l, i64 r) -> i64 {
return prere[r] - prere[l - 1] - sumr(1, l - 1) * sume(l, r);
};
auto sumer = [&](i64 l, i64 r) -> i64 {
return preer[r] - preer[l - 1] - sume(1, l - 1) * sumr(l, r);
};
auto sumed = [&](i64 l, i64 r) -> i64 {
return preed[r] - preed[l - 1] - sume(1, l - 1) * sumd(l, r);
};
auto sumde = [&](i64 l, i64 r) -> i64 {
return prede[r] - prede[l - 1] - sumd(1, l - 1) * sume(l, r);
};
auto sumred = [&](i64 l, i64 r) -> i64 {
return prered[r] - prered[l - 1] - sumr(1, l - 1) * sumed(l, r) - sumre(1, l - 1) * sumd(l, r);
};
auto sumder = [&](i64 l, i64 r) -> i64 {
return preder[r] - preder[l - 1] - sumd(1, l - 1) * sumer(l, r) - sumde(1, l - 1) * sumr(l, r);
};
while (q--) {
i64 l, r;
std::cin >> l >> r;
i64 num = sumr(1, l - 1) * sumde(l, r) - sumr(1, l - 1) * sumed(l ,r) - sumred(l, r) + sumder(l, r) - sumre(l, r) * sumd(r + 1, n) + sumer(l, r) * sumd(r + 1, n);
std::cout << num + prered[n] << '\n';
}
}
signed main() {
std::ios::sync_with_stdio(0);
std::cout.tie(0);
std::cin.tie(0);
i64 t = 1;
// std::cin >> t;
while (t--) {
solve();
}
}
}