二分第二弹
description
我们都知道,ACM比赛的排名认定是解题数目,和解题所需的总时间。现在,你们正在准备打一场比赛,已知题目总数n和每道题的难度a[i],(1 <=a[i]<=1e7).假设你的解题能力是x,(1 <=x <= 1e7),从而你解出一道题所需的时间是ceil(a[i]/x)。你给自己定的目标是在t时间内至少做出k道题,那么问题来了,你在比赛正式开始之前只要要修炼到多少能力值才能达成目标?
ps:ceil()表示向上取整
input
输入多组数据,每组数据第一行是一个整数n,(n < 1000),表示比赛的题目总数,接下来一行是n个整数,表示每道题的难度值。再接下来一行输入一个整数q,(q < 100),表示这组数据里要进行的q次询问。每次询问输入两个整数,t和k,意义如上所述,占一行。(t <= 1e7, k <= n)
output
对每组数据的每次询问,输出你所需的解题能力值x(x也是整数= =),占一行。
sample_input
5
2 4 8 16 32
5
5 4
5 3
10 3
20 5
30 4
sample_output
8
4
2
4
1
hint
解出每道题所需的时间都是整数。
此题的二分还是比较有难度的,当初写这题硬是花费了一下午的时间,不过主要还是得读懂题目意思,不然自己带中间三组数据带到样例里面怎么看也都是错的。所以这题关键在于理解题目,并非样例的数字都是恰好准确,而是要求至少,至少满足了就行,所以以后读题还得仔细理解啦~~下面附上自己一下午的心血:
#include <iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
int ceil(int a,int b)
{
double s=1.0*a/b;
if((int)s-s!=0)
return (int)s+1;
else return (int)s;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int a[1000];
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
int q,t,k;
scanf("%d",&q);
for(int i=0;i<q;i++)
{
scanf("%d%d",&t,&k);
int low=1,high=10000000,mid,s=0,x=0,b[100];
while(low<=high)
{
s=0;
mid=(low+high)/2;
for(int j=0;j<k;j++)
s+=ceil(a[j],mid);
if(s<=t)
{
b[x]=mid;
high=mid-1;
x++;
}
else if(s>t)
low=mid+1;
}
printf("%d\n",b[x-1]);
}
}
return 0;
}
持续更新博客地址:
blog.csdn.net/martinue