Time Limit: 4000MS | Memory Limit: 65536K | |
Description
Shiming (alpc02) is a boy likes to play PopKart very much. He is a good rider in this game. And one day he thought that he became a team leader of a team of N Kart riders.
Today, after the game begins, the riders of his team are now at different places at the racetrack, for that some of the riders got some short cut.
However, we know actually how long has each rider left to run along, and they will ride actually one meter per one time unit (maybe 10ms).
Luckily, Shiming now gets M accelerators, the accelerator can help one rider to ride k meters per one time unit. And all the accelerators are as the same. But one rider can't use more than one accelerator at one time unit.
Shiming is the team leader, and he wants all the team members to finish in the minimal time not just the fastest one to finish the race. He will distribute all the accelerators to the riders.
Note: Here some rules are not as the same as the game we played. At a time unit, Shiming distributes the accelerators to riders for one rider one accelerator, and at the next time unit, all the accelerator can be reused, and Shiming can re-distributes all the accelerators to riders also for one rider one accelerator and the distribution is no relationship with the last time unit.
So you will program to help Shiming to get the actually minimal time the team will use to finish the race.
Input
The input file has T (1<T<20) test cases, and the first line of the file will show the T.
Each of test cases, will be the N (1<= N <= 100000) rider, and N numbers Ai (1<= Ai <= 10^8) show how long will the rider have to finish the race. And the M and the K (1<= K*M <=10^8) for the accelerators.
Output
Sample Input
2 3 2 3 9 1 5 3 2 3 6 1 5
Sample Output
3 2
Source
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int rider, dis[100005], acc, k;
bool check(int m) { //注意!dis[i]非常大,再乘以acc,会int溢出的
long long tot = (long long)acc * m; //一定要注意!int溢出是随时都可能发生的,所以先强制转换,保存起来
long long cnt = 0;
for(int i = 0; i < rider; i++) {
if(dis[i] <= m) continue;
else { //dis[i] <= m的话该车手自己就可以跑到终点
int tmp = (dis[i]-m)/(k-1) + ((dis[i]-m)%(k-1)!=0);//tmp就是当前车手需要的加速次数,向上取整(强制转换有些耗时,不用ceil了吧)
if(tmp > m) return false; //注意!!这说明即使他一直在加速,一个加速器都无法满足该车手
cnt += tmp;
if(cnt > tot) return false;//一旦超过总加速次数,说明次数不够
}
}
return true;
}
int main() {
int cas;
scanf("%d", &cas);
while(cas--) {
int maxi = 0;
scanf("%d", &rider);
for(int i = 0; i < rider; i++){
scanf("%d", dis+i);
if(dis[i] > maxi) maxi = dis[i];
}
scanf("%d%d", &acc, &k);
if(k > 1) {
int l = 1, r = maxi, mid;
while(l <= r) {
mid = (l+r) >> 1;
if(!check(mid)) l = mid + 1; //注意!当check失败的时候,意味着需要更大的答案
else r = mid - 1;
}
printf("%d\n", l);
}
else printf("%d\n", maxi);
}
return 0;
}