[Offer收割]编程练习赛5-1 小Ho的防护盾
#1357 : 小Ho的防护盾
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
小Ho的虚拟城市正在遭受小Hi的攻击,小Hi用来攻击小Ho城市的武器是一艘歼星舰,这艘歼星舰会以T(T为大于0的整数)个单位时间的间隔向小Ho的城市轰击。歼星舰总共有N枚炮弹,其中第i枚会造成Ai点伤害值。
幸好小Ho的城市有K层护盾,每层护盾可以抵挡M点伤害。当某次轰击使得伤害值达或超过M时,该层护盾就会被击碎;该次轰击溢出的伤害不会作用于下一层护盾;下一次轰击将由下一层护盾承受。
同时,受损但尚未被击碎护盾会以每单位时间减少1点伤害值的速度修复自己,直到伤害值降为0。这就意味着小Hi的攻击间隔T越大,小Ho撑过这N枚炮弹的可能性就越大。
那么问题来了,小Hi的攻击间隔T至少需要是多少,小Ho城市的防护护盾才能不被全部击破?
为了使题目不存在歧义,规定:
小Hi的第i次攻击发生在时刻(i-1)*T
小Ho的第i次修复发生在时刻i-0.5
输入
第一行包含3个整数N、M和K,意义如前文所述。
第二行包含N个整数A1 - AN,表示小Hi第i枚炮弹的伤害值。
对于30%的数据,满足N<=100
对于100%的数据,满足1<=N<=100000
对于100%的数据,满足1<=K<=10, 1<=Ai, M<=100000
输出
输出使得小Ho城市的防护护盾不被全部击破的小Hi攻击间隔的最小值。如果不存在这样的T,则输出-1。
- 样例输入
-
3 5 1 3 3 3
- 样例输出
-
3
用C写的。
(1), 明显的二分查找, (开始的时候还想用dp去试,还是太渣!!)
(2), 判定函数注意题目中的规则!
#include <stdio.h> #include <stdlib.h> #include <string.h> int check(int ttime, int n, int m, int k, int* num){ int i,j, atk = 0; for(i=0; i<n; i++){ atk -= ttime; if(atk < 0){ atk = 0; } atk += num[i]; if( atk >= m ){ k--; atk = 0; } } if(k > 0){ return 1; }else{ return 0; } } int main(){ freopen("in.txt", "r", stdin); int i,j, n,m,k, ans; scanf("%d %d %d", &n, &m, &k); int* num = (int *)calloc(n+1, sizeof(int)); for(i=0; i<n; i++){ scanf("%d", &num[i]); } int mid, low = 1, high = m+1; ans = -1; while(low < high){ mid = low + (high - low)/2; if(check(mid, n, m, k, num)){ ans = mid; high = mid; }else{ low = mid + 1; } } printf("%d\n", ans); free(num); return 0; }