2019欢乐友谊赛A题题解
作者:互联网
题目原文:
题目大意:
一条龙开始有X个头,你把它头砍完就胜利了。
你有n种方式去砍头。每一种方式有两个量d与h,表示你先砍掉龙d个头,龙再长出来h个头。
n种方法使用没有顺序,且每种方法可以使用无数次(笑,既然最厉害的大招无CD,那就拼命放大就好了)
思路:
记下来这n种方法中,砍头d最大的那种方法的砍头数为MAXT,(此处不关心这个方法砍完长出来的头数)
情况一:如果龙初始的头比MAXT小,拜拜了,直接用这招砍下去,拜拜了,OTK(一个回合秒杀), 砍完就直接结束游戏,头不会再长。
否则的话,我们不能直接用这一招,因为 不能OTK,龙被砍了d个头,还会长h个头,又恢复了(甚至万一h >d就尴尬了,越打越多),所以
此等大招,留到最后再放,先掐在手里。先找到所有方法中d-h最大的一组,记max(d - h) 为MAXCHA
情况二:排除掉情况一OTK的情况下,若MAXCHA <= 0,再打十年你大学也毕不了业,输出-1吧
剩下就是常规情况了,我们只需要用贪心,前期一直用收益(d与h的差 MAXCHA)最大的方法打龙,
打到龙还有最后一丝血(血量小于MAXT)时,直接往他身上放寒冰惩戒(MAXT那一招,头不会再长出来),这样,
不用担心对方来偷龙了,再去把对面中路兵线清了,赶紧至少拿下一座中塔吧,不然拿龙有啥用呢对吧,中路团,小心对方切后排。
情况三:排除前两种情况,即MAXCHA > 0 时, 前面有MAXCHA对应的招数,当龙的血量在MAXT以下时,直接使用MAXT,
当然,处理的时候可以优化一下: 直接把龙的初始头数X -= MAXT , 总次数先初始化为1 , 再直接用剩下的 X除以MAXCHA得到
的答案再加1就是前面攻击次数(当然如果刚好整除就不用+1了)
PS:最后给出了AK代码, 其中关于d h 涉及到结构体排序。当时脑子不太清楚,其实不太需要。
在读入d h 的时候就可以直接记忆化MAXT和MAXCHA, 并且d与h根本就不需要开数组(结构体数组),
因为只需要MAXT, MAXCHA,所以每次读取时用临时的d h就好了
此处用伪代码改进:伪代码伪代码!!!!!
MAXT = -100000
MAXCHA = -100000
for :
cin >> d >> h
if d > MAXT:
MAXT = d
if d - h > MAXCHA
MAXCHA = d - h
end for;
代码:
#include <iostream> #include <algorithm> using namespace std; typedef long long ll; struct node { ll d; ll h; ll cha; }a[101]; bool cmp(node a, node b) { if(a.cha != b.cha) return a.cha>b.cha; else if(a.d!=b.d) return a.d > b.d; else return a.h < b.h; } int main() { int t; cin >> t; while(t --) { int n;//100 int x;//109 cin >> n >> x; int maxT = -100; int maxCha = -100; for(int i = 0; i < n; ++ i) { cin >> a[i].d >> a[i].h; a[i].cha = a[i].d - a[i].h; if(a[i].d > maxT) maxT = a[i].d; if(a[i].cha > maxCha) maxCha = a[i].cha; } sort(a, a + n, cmp); int num = 0; if(x <= maxT) num = 1; else if(maxCha <= 0) num = -1; else { x -= maxT; num = 1; if(x % a[0].cha == 0) num += x / a[0].cha; else num += x / a[0].cha + 1; } cout << num << endl; } return 0; }
标签:cha,int,题解,ll,cin,MAXT,2019,友谊赛,MAXCHA 来源: https://www.cnblogs.com/Chaosliang/p/11873473.html