CR1037 题解

A

题意 :

输入一个数,找到最小的和它有共同数字的数

思路:

显然就是这个数的所有位数的最小的那一位

void solve()
{
    int n;
    cin >> n;
    string s = to_string(n);
    sort(all(s));
    cout << s[0] << endl;
}

B

题意:

给定一个包含个元素的数组和一个数 ,中的每个元素由 构成,需要我们寻找数量的连续串且每个串之间需要有一个元素相隔

思路:

直接模拟即可

void solve()
{
    int n, k;
    cin >> n >> k;
    vint v(n);
    for (auto &&i : v) {
        cin >> i;
    }
    int cnt = 0;
    int now = 0;
    for (size_t i = 0; i < n; i++)
    {
        if(v[i] == 0)now++;
        if(v[i] == 1)now = 0;
        if(now == k){
            i++;
            cnt++;
            now = 0;
        }
    }
    cout << cnt << endl;
}

C

题意:

给定两个数 和一个有 个元素的数组 ,有一个从开始的每秒加的水位,数组中的元素表示第座塔的高度,你初始在 高度的塔上,你可以花费 的时间从第座塔移动到第座塔,当水位完全超过你所在塔的高度的时候便会失败

你需要判断能否到达最高的塔而不失败

思路:

我们考虑贪心,因为水位上涨速度与我们移动速度是一致的,故只要从我们目前所在高度的 到最高位置 之间从小到大两两的距离差都小于初始高度 我们就可以到达最高的塔

void solve()
{
    int n, k;
    cin >> n >> k;
    vint v(n);
    for (auto &&i : v) {
        cin >> i;
    }
    int under = v[k - 1];
    // 贪心:一开始所在位置就是我们能跨越的最大位置,而且我们只需要看比一开始大的
    ranges::sort(v);
    vint res;
    for (size_t i = 0; i < n; i++) {
        if (v[i] >= under) {
            res.emplace_back(v[i]);
        }
    }
    vint diff(n,0);
    for (size_t i = 0; i + 1 < res.size(); i++) {
        diff[i] = res[i + 1] - res[i];
    }
    cout << (ranges::max(diff) > under ? "NO" : "YES") << endl;
}

D

题意:

给定 个赌场,其有三个参数 ,再给定初始金币 ,规定持有金币数量每个赌场只能允许 进入并且会将 变为 ,并且每个赌场只能进入一次

我们需要知道我们在参加任意次赌场后获得的最大金币数量为多少

思路:

由于我们需要最大的金币数量,所以我们每一次游玩后都想要金币尽可能上涨,这里我们考虑使用 大堆顶 即优先队列来筛选,其存放数据为

具体做法是

  • 先将所有赌场的进入门槛 从小到大排序
  • 然后进行循环,首先令
    • 对当前金币 ,将 的放入大堆顶,这样存放进入的数据中会按照的大小排序
    • 对堆里的数据,先排除
    • 如果堆空了或者堆顶的 的话说明已经没有比 还大的元素了,那么我们就退出循环
    • 否则就将 赋值为堆顶的 代表这一轮找到了最大的 然后重复循环
struct st
{
    int l, r, re;
};
 
void solve()
{
    int n,k;
    cin >> n >> k;
    vector<st> v(n);
    for (size_t i = 0; i < n; i++)
    {
        auto &&[l, r, t] = v[i];
        cin >> l >> r >> t;
    }
    ranges::sort(v, [](st a, st b) { return a.l < b.l; });
    priority_queue<pii> pq;
    int now = k;
    int idx = 0;
    while (1)
    {
        while (idx < n && v[idx].l <= now)
        {
            pq.emplace(v[idx].re, v[idx].r);
            idx++;
        }
        // 排除 r < now的
        while (!pq.empty() && pq.top().second < now)
        {
            pq.pop();
        }
        // 如果空或者没有比x大的,那么就退出
        if (pq.empty() || pq.top().first <= now) {
            break;
        }
        // 提升now
        now = pq.top().first;
        pq.pop();
    }
    cout << now << endl;
}