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;
}
}