A - Candy Button

有一个按钮按下后就能获得一颗糖果,但是有一定的冷却,冷却期间按下就没有糖果。给我一串按下按钮的序列,求最后能获取多少糖果。

思路: 逐个模拟即可,过程中记录上次拿糖果的时间。

#include <bits/stdc++.h>

using namespace std;

int main(){
    int n, c;
    cin >> n >> c;
    vector<int> a(n);
    for (int i = 0;i<n;i++){
        cin >> a[i];
    }
    int res = 1;
    int t = a[0];
    for (int i = 1;i<n;i++) {
        if (a[i] - t >= c) {
            res +=1;
            t=a[i];
        }
    }
    cout << res << endl;
}

B - Hands on Ring (Easy)

两者手握着一个长度为的环。每次移动一只手到指定位置,过程中不可越过另一只手,求总操作步数。

思路:每次判断两个方向哪个方向不能走,然后走另一条路。通过绝对值求距离。

#include <bits/stdc++.h>

using namespace std;

int main(){
    int n, l;
    cin >> l >> n;
    getchar();
    char hand; int target;
    int lh = 1, rh = 2;
    int res = 0;
    for (int i = 0;i<n;i++){
        int step;
        scanf("%c %d\n", &hand, &target);
        if (hand == 'L'){
            step = abs(target - lh);
            if (step * 2 < l) {
                if ((target < rh && rh < lh) || (target > rh && rh > lh)) step = l - step;
            } else {
                if (((target < rh && rh < lh) || (target > rh && rh > lh))) step = l - step;
            }
            lh = target;
        } else if(hand == 'R') {
            step = abs(target - rh);
            if (step * 2 < l) {
                if ((target < lh && lh < rh) || (target > lh && lh > rh)) step = l - step;
            } else {
                if (((target < lh && lh < rh) || (target > lh && lh > rh))) step = l - step;
            }
            rh=target;
        } else {
            *((int*)0) = 1;
        }
        res += step;
    }
    cout << res << endl;
}

C - Prepare Another Box

给你n个玩具和n-1个箱子,然后让你买一个箱子使得所有玩具都能放进不同一个箱子,要求新买的箱子尽可能小。没有答案输出-1,否则输出购买的箱子大小。

思路:最后购买的箱子的大小肯定是一个不能装进现有箱子的玩具的大小,将箱子和玩具降序,然后一一匹配,如果只有一个玩具装不下,输出该玩具的大小,否则输出-1。

#include <bits/stdc++.h>

using namespace std;

int main(){
    int n; cin >> n;
    vector<int> a(n),b(n-1);
    for (int i = 0; i<n;i++){
        cin >> a[i];
    }
    for (int i = 0; i<n-1;i++){
        cin >> b[i];
    }
    sort(a.begin(), a.end(), greater()); sort(b.begin(), b.end(), greater());
    int flag = 0;
    for (int i = 0,j=0; i<n && j<n-1;i++,j++){
        if (a[i] > b[j]) {
            if (flag == 0){
                flag = a[i];
                j--;
            } else {
                flag = -1;
                break;
            }
        }
    }
    if (flag == 0) flag = a[n-1];
    cout << flag << endl;
}

D - Cycle

给你一个简单有向图,输出包含节点1的最短的环的长度,没有环输出-1.

思路: 很明显的bfs从1出发,遇到第一个环就可以停止了。

#include <bits/stdc++.h>

using namespace std;

int main(){
    int n,m;
    cin >> n>>m;
    vector<vector<int>> ns(n);
    for (int i = 0;i<m;i++){
        int a, b;
        cin >> a >> b;
        ns[a-1].push_back(b-1);
    }
    queue<pair<int, int>> q;
    q.push({0,1});
    bool flag =false;
    int res = 0;
    while(!q.empty()){
        auto e = q.front(); q.pop();
        if(e.first == 0 && e.second != 1){
            res = e.second;
            break;
        }
        for (auto i : ns[e.first]){
            q.push({i, e.second+1});
        }
    }
    cout << res - 1 << endl;
}

E - Max × Sum

给出两个长为N有序数组A,B。在1~N中选择K个数字作为下标,使得每个下标i对应的Ai的最大值*每个下标i对应的Bi的和最小,输出这个最小值。

思路: 可以利用枚举和贪心,先从小到大枚举Ai的值,同时维护K个Bi的和。枚举过程通过给A列表排序,逐个枚举Ai,然后不断加入新的Ai,淘汰旧的Ai,将要淘汰的Ai用贪心决定即Bi最大值对应的Ai,所以要维护Bi的最大值,可以用优先队列。枚举过程中res不断取较小值。最后的res即为答案。

#include <bits/stdc++.h>

using namespace std;
void solve(){
    long long n,k;
    cin >> n >> k;
    long long a[n], b[n];
    for(long long i =0;i<n;i++) cin >> a[i];
    for(long long i =0;i<n;i++) cin >> b[i];
    vector<pair<long long, long long>> ns(n);
    for(long long i =0;i<n;i++) {ns[i] = {a[i], b[i]};};
    sort(ns.begin(), ns.end());
    long long res = INTMAX_MAX;
    priority_queue<pair<long long, long long>> heap;
    long long sum = 0;
    long long maxx = ns[k-1].first;
    for (long long i = 0; i<k;i++) {
        heap.push({ns[i].second, ns[i].first});
        sum+=ns[i].second;
    }
    for(long long i = k;i<n;i++){
        res = min(res, sum*maxx);
        auto e= heap.top();
        heap.pop();
        sum-=e.first;
        heap.push({ns[i].second, ns[i].first});
        sum+=ns[i].second;
        maxx=ns[i].first;
    }
    res = min(res, sum*maxx);
    cout << res << endl;
}
int main(){
    long long tcs; cin >> tcs;
    while(tcs--) solve();
}