题目描述

有两种糖:

  • 棒棒糖:有 aa 颗,每颗需要 xx 分钟
  • 软糖:有 bb 颗,每颗需要 yy 分钟

总时间为 mm 分钟,求最多能吃多少颗糖。


思路

这是一个简单的贪心问题:

优先吃耗时更少的糖。


做法

  • 如果 xyx \le y
    • 先吃棒棒糖
    • 再吃软糖
  • 否则:
    • 先吃软糖
    • 再吃棒棒糖

每一步都取:

min(数量,m/时间)\min(数量, \lfloor m / 时间 \rfloor)

m/时间\lfloor m / 时间 \rfloorm/时间m/时间向下取整


代码

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

int main() {
    int a, b, x, y, m;
    cin >> a >> b >> x >> y >> m;

    int ans = 0;

    if (x <= y) {
        int t = min(a, m / x);
        ans += t;
        m -= t * x;

        ans += min(b, m / y);
    } else {
        int t = min(b, m / y);
        ans += t;
        m -= t * y;

        ans += min(a, m / x);
    }

    cout << ans;
}

复杂度

时间复杂度:O(1)O(1)
空间复杂度:O(1)O(1)


总结

优先吃耗时少的糖。

思路

直接枚举每个 aa,判断它是否能和 x,yx, y 构成:

  • 加法关系:
    x+y=ax+y=ax+a=yx+a=yy+a=xy+a=x
  • 乘法关系:
    x×y=ax\times y=ax×a=yx\times a=yy×a=xy\times a=x

满足任意一个条件即可计数,并更新最大值。


做法

遍历每个 aa

  • 满足条件 → 计数 +1
  • 同时更新最大值

代码

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

int main() {
    int n;
    long long x, y;
    cin >> n >> x >> y;

    int cnt = 0;
    long long mx = -1;

    while (n--) {
        long long a;
        cin >> a;

        if (x + y == a || x + a == y || y + a == x ||
            x * y == a || x * a == y || y * a == x) {
            cnt++;
            mx = max(mx, a);
        }
    }

    cout << cnt << ' ' << mx;
}

复杂度

时间复杂度:O(n)O(n)
空间复杂度:O(1)O(1)


总结

枚举 + 判断即可。

思路

按照题意:

  • 每遇到一个元音字母(a,e,i,o,u),就在它后面切一刀
  • 每一段取第一个字母并大写

等价转化:

  • 第一个字母一定输出
  • 对于每个元音位置 i,输出 s[i+1] 的大写

做法

  • 输出 s[0] 的大写
  • 遍历字符串:
    • 如果 s[i] 是元音
      • 输出 s[i+1] 的大写

代码

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

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;

    while (T--) {
        string s;
        cin >> s;

        cout << char(s[0] - 32);

        int n = s.size();

        for (int i = 0; i < n - 1; i++) {
            if (s[i]=='a'||s[i]=='e'||s[i]=='i'||s[i]=='o'||s[i]=='u') {
                cout << char(s[i+1] - 32);
            }
        }

        cout << '\n';
    }

    return 0;
}


总结

找所有元音位置,输出下一位字符的大写。

思路

暴力枚举所有子矩阵:

  • 枚举 (r1, r2, c1, c2)
  • 统计子矩阵中不同颜色数量
  • 若等于 d,更新面积

代码(详细注释)

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

int a[30][30];

int main() {
    int n, m, d;
    cin >> n >> m >> d;

    // 读入矩阵
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> a[i][j];
        }
    }

    int ans = -1; // 最大面积,-1 表示无解

    // 枚举上边界
    for (int r1 = 0; r1 < n; r1++) {

        // 枚举下边界
        for (int r2 = r1; r2 < n; r2++) {

            // 枚举左边界
            for (int c1 = 0; c1 < m; c1++) {

                // 枚举右边界
                for (int c2 = c1; c2 < m; c2++) {

                    int T[410] = {0}; // 统计颜色出现次数
                    int cnt = 0;      // 当前不同颜色数

                    // 遍历子矩阵
                    for (int i = r1; i <= r2; i++) {
                        for (int j = c1; j <= c2; j++) {

                            int color = a[i][j];
                            T[color]++;

                            // 第一次出现该颜色
                            if (T[color] == 1) {
                                cnt++;
                            }
                        }
                    }

                    // 若颜色种数刚好为 d
                    if (cnt == d) {
                        int area = (r2 - r1 + 1) * (c2 - c1 + 1);
                        ans = max(ans, area);
                    }
                }
            }
        }
    }

    // 输出答案
    if (ans == -1) cout << "Hrk\n";
    else cout << ans << '\n';

    return 0;
}

复杂度

时间复杂度:O(n^3 m^3)
空间复杂度:O(1)


总结

枚举所有子矩阵 + 统计不同颜色数量。

0 条评论

目前还没有评论...