【补题】Educational Codeforces Round 85 (Rated for Div. 2)

C题直接贪心,D题欧拉回路,理论上应该会做的……
然后应该读题比较慢的关系,A题+B题各做了20分钟……还是15分钟内连切两道比较理想,毕竟挂了梯子,开CF的速度也不慢。


C. Circle of Monsters

\(n\)只怪物站成一圈,第\(i\)只怪物有\(a[i]\)点生命值和\(b[i]\)点爆炸伤害。当第\(i\)只怪物死亡时会爆炸,且只对第\(i+1\)只怪物造成\(b[i]\)点伤害。爆炸可以传递。每次开枪会对其中一只怪物造成\(1\)点伤害,求能杀死全部怪物的最小开枪次数。

这题的数据范围有点emmm,我还以为要想办法写\(O(1)\)来着,其实是\(O(n)\)

对每只怪物视为首个击杀目标,计算要补枪的次数(就是其它怪物扣除爆炸伤害后的剩余血量)遍历n只就好,用set维护最小值(感觉get到了什么新用法……)。

注意\(n==1\)时特判一下。

#include<iostream>
#include<map>
#include<cstring>
#include<math.h>
#include<algorithm>
#include<set>
using namespace std;

const int N = 1e5 + 5;

int main()
{
    int q;
    cin >> q;
    while (q--) {
        int n;
        cin >> n;
        long long int arr[N], pow[N], shrey[N];
        set<long long int> s;
        cin >> arr[0] >> pow[0];
        if (n == 1) {//只有一只怪物,特判
            cout << arr[0] << endl;
            continue;
        }
        long long int sum = 0;//不会被直接炸死的怪物的剩余血量
        for (int i = 1;i < n;i++) {
            cin >> arr[i] >> pow[i];
            shrey[i] = arr[i] - pow[i - 1];//shrey[i]是第i只怪物被炸后的剩余血量
            if (shrey[i] > 0) {//不会被直接炸死
                sum += shrey[i];//剩余血量
            }
        }
        shrey[0] = arr[0] - pow[n - 1];
        if (shrey[0] > 0) sum += shrey[0];
        for (int i = 0;i < n;i++) {
            if (shrey[i] > 0) {
                s.insert(sum - shrey[i] + arr[i]);
                //总残余血量-这只怪物残余血量+这只怪物生命值
                //即将它视为首个目标时需要的子弹数量
            }
            else {
                s.insert(sum + arr[i]);//总残余血量-(0)+生命值
            }
        }
        cout << *s.begin() << endl;//输出最小值
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/streamazure/p/12677497.html