Survivor

Survivor

(https://codeforces.com/group/L9GOcnr1dm/contest/422378/problem/F)

血的教训

比较有意思的一个贪心题

简单翻译一下题目:
输入第一行n,m,k;分别代表有几个人,几分钟,和总共能治疗的次数
输入第二行n个数,代表他们个别的初始血量
第三行n个数,代表每分钟他们会被扣掉的血
第四行,代表如果你用技能可以给这个人加多少血
问你,最后一共能活多少个人

看到题目第一想法就是用每轮加的血量去比较能不能救活,毫无列外t了(没看好k的数据范围,到1e11了

code

while (1){
        co++;
        for (int i = 1; i <= n; i++) {
            toadd[i]+=ad[i];
            if(toadd[i] + hp[i] > 0 && !vis[i]){
                k-=co;
                if(k >= 0){
                    count++,vis[i] = true;
                }
            }
        }
        if(co >= k || k == 0){
            cout << count << endl;
            return 0;
        }
    }
既然t了那换个思路。首先人得活到m分钟后,也就是说连带加血,你m分钟后的血量一定得大于0。那么就是计算出m分钟后他们所剩的血量,然后用这个血量去除于每次他们每个人能加的血量再加上1,就是他们m分钟后需要治疗多少次就能存活了
这里注意三点,一:有可能他们m分钟后血量还是正的。二:有可能m分钟后他们的血量刚好为0。三:为啥要加1呢,如果他们的剩余的血量刚好可以整除他们每次加的血量,那么治疗后他们的血量刚好是0,依旧是不能活的

Acode

ll count = 0;
    vector<ll> co(n+1);
    co[0] = -1;
    for (int i = 1; i <= n; i++) {
        if(hp[i] > 0)co[i] = 0;
        else if(hp[i] == 0)co[i] = 1;
        else co[i] = abs(hp[i])/ad[i]+1;
    }
    sort(co.begin(),co.end(),cmp);
    for (int i = 1; i <= n; i++) {
        k -= co[i];
        if(k >= 0)count++;
        else break;
    }
    cout << count << endl;

还有一个特别有意思的

wacode

ll count = 0;
    vector<ll> co(n+1);
    co[0] = -1;
    for (int i = 1; i <= n; i++) {
        if(hp[i] > 0)co[i] = 0;
        else if(hp[i] == 0)co[i] = 1;
        else co[i] = abs(hp[i])/ad[i]+1;
    }
    sort(co.begin(),co.end(),cmp);
    for (int i = 1; i <= n; i++) {
        k -= co[i];
        if(k >= 0)count++;
        else {
            cout << count << endl;
            return 0;
        }
    }

两个代码相差很小,但是由于提前输出就给wa了,所以千万不能提前输出!千万不能提前输出!千万不能提前输出!

posted @ 2023-01-19 01:10  TFOREVERY  阅读(39)  评论(0编辑  收藏  举报