视频题解

A

- 50pts

使用循环模拟每次吃的情况,判断能否达到爆爽范围

-100pts

kk 为吃的包数,即:0.9nk×mn0.9n≤k×m≤n 满足该不等式则输出 Yes,否则输出 No

求出满足最低爆爽辣度要求的最小包数 kmink_{min}​:需要满足 kmin×m0.9nk_{min}​×m≥0.9n,对 0.9nm\frac{0.9n}m​ 做向上取整; 不超过辣度上限的最大包数 kmaxk_{max}​:需要满足 kmax×mnk_{max}​×m≤n,对 nm\frac{n}m​ 做向下取整。

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    double low = 0.9 * n;  // 爆爽下限
    int up = n;            // 爆爽上限
    
    // 核心公式:计算最小包数(向上取整)、最大包数(向下取整)
    int min_k = ceil(low / m); 
    int max_k = up / m;
    
    cout << (min_k <= max_k ? "Yes" : "No") << endl;
    
    return 0;
}

B

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int y; cin >> y;
    int k = sqrt(y);
    if (k * k != y) {
        cout << "No";
        return 0;
    }
    if (y % 400 == 0 || y % 4 == 0 && y % 100)
        cout << "Yes";
    else    
        cout << "No";
    return 0;
}

C

#include <iostream>
#include <vector>
using namespace std;

bool ok(int x) {
    if (x < 10) return 1;
    int a = x % 10;
    x /= 10;
    while (x) {
        int b = x % 10;
        if ((a - b > 2) || (b - a > 2)) return 0;
        a = b;
        x /= 10;
    }
    return 1;
}

int main() {
    int n, cnt = 0, num = 0;
    cin >> n;
    while (cnt < n) {
        num++;
        if (ok(num)) cnt++;
    }
    cout << num << endl;
    return 0;
}

D

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);  
    cin.tie(nullptr);
    
    int t; cin >> t;
    while (t--) {
        int n; cin >> n;
        long long sm = 0;  
        int cnt0 = 0, cnt1 = 0, cnt2 = 0;  // 统计余0、1、2的元素数量
        
        for (int i = 1; i <= n; ++i) {
            int x; cin >> x;
            sm += x;
            int m = x % 3;
            if (m == 0) cnt0++;
            else if (m == 1) cnt1++;
            else cnt2++;
        }
        
        int mod = sm % 3;
        int ans = n; 
        
        if (mod == 0) ans = 0;  // 总和已是3的倍数,无需删除
        else if (mod == 1) {
            // 方案1:删1个余1的元素;方案2:删2个余2的元素
            if (cnt1 >= 1) ans = min(ans, 1);
            else           ans = min(ans, 2);
        } else {  
            // 方案1:删1个余2的元素;方案2:删2个余1的元素
            if (cnt2 >= 1) ans = min(ans, 1);
            else           ans = min(ans, 2);
        }
        
        cout << ans << endl;
    }
    return 0;
}

E

注意 1k131\le k \le 13,也就是说修改某段的重复字母一定可以不影响更靠后的子段。

模拟题目要求的过程即可

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int T = 1;
    while (T--)
    {
        int N, K;
        cin >> N >> K;
        string s;
        cin >> s;
        int cnt[300] = {0};
        int ans = 0;
        for (int l = 0, r = 0; r <= N;)
        {
            if (r - l < K)
            {
                cnt[s[r]]++;
                r++;
                continue;
            }
            for (char c = 'a'; c <= 'z'; c++)
            {
                if (cnt[c] > 1)
                {
                    int t = cnt[c] - 1;
                    ans += t;
                    for (int j = r - 1; j >= l; j--)
                        if (s[j] == c && t)
                            s[j] = ' ', t--;
                    cnt[c] = 1;
                }
            }
            cnt[s[l]]--;
            l++;
        }

        cout << ans << '\n';
    }
    return 0;
}

F

首先我们要求出最大得分是多少,也就是尽量删除尽可能多的 aa,那么 aa 靠前的数字就要大一些,因此我们不难想到最优情况实际上就是把 aa 降序排列。

此时我们模拟一遍就会发现,对于 bb 中的最小值 minbmin_b ,所有 aa 中大于 minbmin_b 的数字一定都会被删除,而反之小于 minbmin_b 的数字是不可能被删除的。

因此最大的得分实际上就是 aa 中大于 minbmin_b 的数字个数。

此时我们考虑如何求方案数,也就是说还有哪些情况也能使得答案取到上述的个数。

那么再次模拟一遍,我们会发现实际上只需要把 aa 中大于 minbmin_b 的所有数字都放在开头的部分,而剩下的部分放在后面,即将 aa 分成两段,第一段全是大于 minbmin_b 的数,第二段全是小于 minbmin_b 的。

我们发现此时必然也能取到答案,而如果不是这样的情况,则必然取不到,因为会把minbmin_b 删掉,导致后面的 aa 更难被删除。

因此前一段随意排列,后一段随意排列,答案就是两段长度的阶乘之积。(乘法原理)

#include <bits/stdc++.h>
using namespace std;
int MOD = 1e9 + 7;
int main()
{
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    int mn = 2e9;
    for (int i = 1, x; i <= n; i++)
    {
        cin >> x;
        mn = min(mn, x);
    }
    int x = 0, y = 0;
    for (int i = 1; i <= n; i++)
    {
        if (a[i] > mn)
        {
            x++;
        }
        else
        {
            y++;
        }
    }
    long long ans = 1;
    for (int i = 1; i <= x; i++)
    {
        ans = (ans * i) % MOD;
    }
    for (int i = 1; i <= y; i++)
    {
        ans = (ans * i) % MOD;
    }
    cout << ans << endl;
    return 0;
}

0 条评论

目前还没有评论...