牛客周赛 Round 63

A.小红的好数

题意:

满足数位为2, 且个位数和十位数相等

思路:

通过输入字符串, 首先判断字符串的个数是否为2, 在判断个位数和十位数是否相等

复杂度:

O(1)

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <bits/stdc++.h>
     
using namespace std;
using i64 = int64_t; 
 
void solve() {
    string s;
    cin >> s;
    if (s[0] == s[1] && s.size() == 2) {
        cout << "Yes\n";
    } else {
        cout << "No\n";
    }
}
 
int main() {
    cin.tie(0) -> sync_with_stdio(false);
    int t = 1;
    // cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

B.小红的好数组

题意:

找到区间为k长度的连续区间且不是回文数组但是可以修改一次得到回文数组, 计算当前满足回文数组条件的个数

思路:

直接暴力枚举长度为k的连续区间, 判断是否修改一次满足是回文数组

复杂度:

O(n * k)

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <bits/stdc++.h>
  
using namespace std;
using i64 = int64_t;
     
void solve() {
    int n, k;
    cin >> n >> k;
    vector <int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    int ans = 0;
    for (int i = 0; i <= n - k; i++) {
        vector <int> b(a.begin() + i, a.begin() + i + k);
        int cnt = 0;
        for (int l = 0, r = k - 1; l < r; l ++, r --) {
            if (b[l] != b[r]) {
                cnt++;
                if (cnt > 1) {
                    break;
                }
            }
        }
        if (cnt == 1) {
            ans++;
        }
    }
    cout << ans << '\n';
}
 
int main() {
    cin.tie(0) -> sync_with_stdio(false);
    int t = 1;
    // cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

C.小红的矩阵行走

题意:

从(0, 0)出发, 只能走下或右且每走一步都收集数字, 走到(n - 1, m - 1)且所有收集的数字都是相同的

思路:

一道基础的板子题, 写法很多

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <bits/stdc++.h>
     
using namespace std;
using i64 = int64_t;
constexpr int N = 1e2 + 5;
int dirs[3] = {1, 0, 1}, n, m, a[N][N];
bool ok = 1;
 
bool check (int x, int y) {
    return x >= 0 && x < n && y >= 0 && y < m;
}
 
void dfs (int x, int y) {
    if (x == n - 1 && y == m - 1) {
        ok = 0;
        return ;
    }
    for (int i = 0; i < 2; i++) {
        int dx = dirs[i] + x, dy = dirs[i + 1] + y;
        if (check(dx, dy) && a[dx][dy] == a[0][0]) {
            dfs(dx, dy);
        }
    }
}
 
void solve() {
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> a[i][j];
        }
    }
    ok = 1;
    dfs(0, 0);
    cout << (!ok? "Yes" : "No") << '\n';
}
 
int main() {
    cin.tie(0) -> sync_with_stdio(false);
    int t = 1;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}
 
#include <bits/stdc++.h>
     
using namespace std;
using i64 = int64_t;
constexpr int N = 1e2 + 5;
int dirs[3] = {1, 0, 1}, a[N][N], n, m;
 
bool check (int x, int y) {
    return x >= 0 && x < n && y >= 0 && y < n;
}
 
void solve() {
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> a[i][j];
        }
    }
    queue <pair<int, int>> q;
    q.push({0, 0});
    while (!q.empty()) {
        auto [x, y] = q.front(); q.pop();
        if (x == n - 1 && y == m - 1) {
            cout << "Yes" << '\n';
            return ;
        }
        for (int i = 0; i < 2; i++) {
            int dx = dirs[i] + x, dy = dirs[i + 1] + y;
            if (check(dx, dy) && a[dx][dy] == a[0][0]) {
                q.push({dx, dy});
            }
        }
    }
    cout << "No" << '\n';
}
 
int main() {
    cin.tie(0) -> sync_with_stdio(false);
    int t = 1;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}
 
#include <bits/stdc++.h>
     
using namespace std;
using i64 = int64_t;
constexpr int N = 1e2 + 5;
int n, m, dp[N][N], a[N][N];
 
void solve() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> a[i][j];
            dp[i][j] = 0;
        }
    }
    dp[1][1] = 1;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (i == 1 && j == 1) continue;
            if (a[i][j] != a[1][1]) continue;
            dp[i][j] = (i > 1 ? dp[i - 1][j] : 0) || (j > 1 ? dp[i][j - 1] : 0);
        }
    }
    cout << (dp[n][m] ? "Yes" : "No") << '\n';
}
 
int main() {
    cin.tie(0) -> sync_with_stdio(false);
    int t = 1;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

  

D:小红的行列式构造

题意:

构造一个3阶行列式, 满足每个元素的绝对值不小于1, 且最后的值等于x

思路:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[a, b, c]
[d, e, f]
[g, h, i]
公式  a * e * i + b * f * g + c * d * h - c * e * g - a * f * h - b * d * i
 
-> a * (e * i - f * h) + b * (f * g - d * i) + c * (e * g - d * h)
假设a, b, c都是相同的, 及我们令他们为1
得到
-> e * i - f * h + f * g - d * i - e * g + d * h
如果继续假设d, e, f都相同, 这样导致了最终的结果为0, 也就是得到第一个结论
-> d * (h - i) + e * (i - g) + f * (g - h)
那么为了简单, 我们令d为2, e, f都为1, 那么我们可以得到
-> 2 * (h - i) + (i - g) + g - h
最终得到这个公式
-> h - i == x
h - i = x 那么只要满足这个式子都可以, 那么我可以假设i = 101那么我的h就是x + 101
为什么不能是x + (值 < 101) 是因为行列式的值的绝对值需要大于等于x也就因为这, 最小情况只能是[g, x + 101 x]
其次发现g在这个式子是直接被约掉的, 那么abs(g) >= 1的值都可以
那么这题就顺利解决了

  

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <bits/stdc++.h>
     
using namespace std;
using i64 = int64_t; 
 
void solve() {
    int x;
    cin >> x;
    if (x == 0) {
        cout << "1 1 1\n1 1 1\n1 1 1\n";
    } else {
        cout << "1 1 1\n2 1 1\n" << 2 << ' ' << x * 2 << ' ' << x << '\n';
    }
}
 
int main() {
    cin.tie(0) -> sync_with_stdio(false);
    int t = 1;
    // cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

E.小红的 red 计数

题意:

给定一个字符串, 若干查询, 每一次查询翻转[l, r]的字符串, 在输出此时red为子串的个数是多少 (每次查询不会真正的翻转区间)

思路1(也是第一个思路):

线段树

维护区间r-e-d的各个组合的值, 得到red的总和sum, 在区间翻转的时候, 导致长度>=2的字符串受到了影响, red 和 der, ed和de, re和ed, 去维护失去和得到的最后就是最终的答案 得到公式

1
2
sum - res1.red + res1.der - res1.re * res3.d + res1.er * res3.d
        - res2.r * res1.ed + res2.r * res1.de

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <bits/stdc++.h>
     
using namespace std;
using i64 = int64_t;
constexpr int N = 1e5 + 5;
int n, q;
string s;
struct SegTree {
    i64 r, e, d, re, er, ed, de, red, der;
} seg[N << 2];
// r e d re ed er de red der
void pushup (SegTree &n1, SegTree &n2, SegTree &n3) {
    n1.r = n2.r + n3.r;
    n1.e = n2.e + n3.e;
    n1.d = n2.d + n3.d;
    n1.re = n2.re + n3.re + n2.r * n3.e;
    n1.er = n2.er + n3.er + n2.e * n3.r;
    n1.ed = n2.ed + n3.ed + n2.e * n3.d;
    n1.de = n2.de + n3.de + n2.d * n3.e;
    n1.red = n2.red + n3.red + n2.r * n3.ed + n2.re * n3.d;
    n1.der = n2.der + n3.der + n2.d * n3.er + n2.de * n3.r;
}
 
void build (int l, int r, int rt) {
    if (l == r) {
        seg[rt] = {s[l] == 'r', s[l] == 'e', s[l] == 'd', 0, 0, 0, 0, 0, 0};
        return ;
    }
    int mid = (l + r) >> 1;
    build (l, mid, rt << 1);
    build (mid + 1, r, rt << 1 | 1);
    pushup (seg[rt], seg[rt << 1], seg[rt << 1 | 1]);
}
 
SegTree query (int L, int R, int l, int r, int rt) { // [L, R] -> (1, n)
    if (L > R) return {0};
    if (L <= l && R >= r) {
        return seg[rt];
    }
    int mid = (l + r) >> 1;
    SegTree res1 = {0}, res2 = {0};
    if (mid >= L) {
        res1 = query(L, R, l, mid, rt << 1);
    
    if (mid < R) {
        res2 = query(L, R, mid + 1, r, rt << 1 | 1);
    }
    SegTree res3 = {0};
    pushup (res3, res1, res2);
    return res3;
}
 
void solve() {
    cin >> n >> q;
    cin >> s;
    s = '$' + s;
    build (1, n, 1);
    i64 sum = query (1, n, 1, n, 1).red;
    while (q--) {
        int l, r;
        cin >> l >> r;
        SegTree res1 = query(l, r, 1, n, 1); // [l, r]
        SegTree res2 = query(1, l - 1, 1, n, 1); // [1, l - 1]
        SegTree res3 = query(r + 1, n, 1, n, 1); // [r + 1, n]
    // re er d
    // red der
    // r ed r de
        cout << sum - res1.red + res1.der - res1.re * res3.d + res1.er * res3.d
        - res2.r * res1.ed + res2.r * res1.de << '\n';
        ;
    }
}
 
int main() {
    cin.tie(0) -> sync_with_stdio(false);
    int t = 1;
    // cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

F.小红开灯

高斯消元

posted @   Iter-moon  阅读(66)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示