原题链接

A

image-20260122201612729

题解:

对四则运算依次判断,除法需要多判断一下是否可以整除。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <bits/stdc++.h>
using namespace std;

int a, b, c;
bool f = false;

int main(){
cin >> a >> b >> c;
if (a + b == c) f = true;
else if (a - b == c) f = true;
else if (a * b == c) f = true;
else if (a % b == 0 && a / b == c) f = true;
if (f) cout << "YES" << endl;
else cout << "NO" << endl;
}

B

image-20260122192253066

题解:

对于每一个需要判断的区间,利用函数判断其合法性。模拟题目,考验代码基本功。

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
#include <bits/stdc++.h>
using namespace std;

int t;
int a[10][10];

void check(int sx, int sy, int ex, int ey, bool &f)
{
int b[5] = {0};
for (int i = sx; i <= ex; i++)
for (int j = sy; j <= ey; j++)
b[a[i][j]]++;

for (int i = 1; i <= 4; i++)
{
if (b[i] != 1)
f = false;
}
}

void solve()
{
for (int i = 1; i <= 4; i++)
for (int j = 1; j <= 4; j++)
cin >> a[i][j];
bool f = true;
for (int i = 1; i <= 4; i++){
check(i, 1, i, 4, f);
check(1, i, 4, i, f);
}
check(1, 1, 2, 2, f);
check(1, 3, 2, 4, f);
check(3, 1, 4, 2, f);
check(3, 3, 4, 4, f);
if (f) cout << "YES" << endl;
else cout << "NO" << endl;
}

int main(){
cin >> t;
while (t--) solve();
}

C

image-20260122192925624

题解

从高位往低位找大于等于5的数

  1. 能找到

    那么直接往高位加一,后面全部为0

  2. 找不到

    个位为0,十位加一

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
#include <bits/stdc++.h>
using namespace std;

int t;

void solve()
{
string s; cin >> s;
int n; n = s.size();
if (s[0] >= '5'){
cout << 1;
for (int i = 1; i <= n; i++)
cout << 0;
cout << endl;
return;
}
int p = -1;
for (int i = 1; i < n; i++)
if (s[i] >= '5'){
p = i;
break;
}
if (p != -1){
s[p - 1]++;
string t;
t = s.substr(0, p);
cout << t;
for (int i = 1; i <= n - p; i++)
cout << 0;
cout << endl;
return;
}
else{
s[n - 1] = '0';
cout << s << endl;
}
}

int main(){
cin >> t;
while (t--) solve();
}

D

image-20260122193629040

乱写得了190/200分,稍微改一改就0分了,真服了。

题解

这份 AC 代码的核心逻辑是 “贪心 + 组合数学 + 前缀积”

题目本质是在寻找能够构成形如 {1,1},{1,1,2,2},{1,1,2,2,3,3}\{1,1\}, \{1,1,2,2\}, \{1,1,2,2,3,3\} 这样结构的子序列个数。

  1. 使用 std::map<int, int> 来统计数组中每个数字出现的次数。

    注:map会自动根据first值进行排序

  2. 判断连续性,差值为1且数量大于等于2,否则终止循环

  3. 计算组合数Ce2C_e^2

    我当时没有做出来的原因就在这里,我犯了错误

    我计算组合数时候使用了O(n)的阶乘方法计算,然而还把组合数计算公式记错了(笑),回顾一下排列数和组合数的计算公式:

    Anm=n!(nm)!A_n^m = \frac{n!}{(n-m)!}

    Cnm=Anmm!=n!m!(nm)!C_n^m = \frac{A_n^m}{m!} = \frac{n!}{m!(n-m)!}

    题目中需要计算$$k = C_e^2$$ 其实可以通过化简得到$$ \frac{e \times (e-1)}{2}$$省略了通过阶乘计算的过程。

    本题最坑的点在于 整数溢出

    1
    ls k = (e*(e-1)/2) % mod;

    由于e定义的是int类型,可能导致运算时候爆Int,依次需要类型转换

    1
    2
    // 乘上 1LL 将计算提升为 long long 类型
    ls k = (1LL * e * (e - 1) / 2) % mod;

    完整代码

    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
    #include <bits/stdc++.h>
    using namespace std;

    typedef long long ls;
    const int N = 2e5 + 10;
    const long long mod = 998244353;
    int t;

    void solve()
    {
    map<int, int> mp;
    int n; cin >> n;
    for (int i = 0; i < n; i++) {
    int x;
    cin >> x;
    mp[x]++;
    }

    ls sum = 0;
    int last = 0; //上一个数是什么
    ls p = 1; //之前的阶乘和
    for (auto [s, e] : mp){
    if (s - last == 1 && e >= 2){
    ls k = (1LL * e*(e-1)/2) % mod;//转成long long类型
    p = (p * k) % mod;
    sum = (sum + p) % mod;
    last = s;
    }
    else break;
    }
    cout << sum << endl;
    }

    int main(){
    ios::sync_with_stdio(0);cin.tie(0);
    cin >> t;
    while (t--) solve();
    }