复印计费问题
时间限制(普通/Java) :
1000 MS/ 3000 MS 运行内存限制 : 65536 KByte
总提交 : 325 测试通过 : 46
总提交 : 325 测试通过 : 46
比赛描述
南邮ACM复印社最近开张,为吸引更多同学们来复印,社长决定按照复印页数规模,分等级进行计费,例如,可以采用以下计费策略:少于100页,每页收费2角;不少于100页,每页只收费1角。有些同学非常聪明,他要复印99页时,故意多复印一页空白页,这样他只需付费100×1角,而不是99×2角。
现在,已知南邮ACM复印社的计费策略和多名同学需要复印的页数,请你告诉这些同学完成复印最少需要多少钱。
输入
输入包含3行。
第1行给出两个整数n和t(0<n, t≤104).
第2行给出2n个整数 p1,q1,p2,q2,…,pn,qn (0= p1< p2<…< pn≤106,106≥q1≥q2≥…≥qn≥0),这里,当复印不少于pi页但少于pi+1页时,每页收费qi角(i=1..n-1);当复印不少于pn页时,每页收费qn角。
第3行依次给出t名同学需要复印的页数。
上述所有整数之间以空格分隔。
输出
针对t名同学需要复印的页数,按行依次输出每名同学完成复印最少需要的钱数(单位为角)。
样例输入
3 4
0 3 100 2 200 1
0 99 100 200
样例输出
0
200
200
200
提示
可用long long定义64位整数,输出格式符为%I64d
题目来源
ZJU_ACM
#include<stdio.h>
#define N 10000
long long p[N],q[N],min[N];
int main(){
int n,t,i,j,mid;
long long number,cost;
scanf("%d%d",&n,&t);
for(i=0;i<n;i++){
scanf("%I64d%I64d",p+i,q+i);
}
min[n-1]=p[n-1]*q[n-1];
for(i=n-2;i>0;i--){
min[i] = p[i]*q[i];
if(min[i]>min[i+1]){
min[i]=min[i+1];
}
}
while(t--){
scanf("%I64d",&number);
i=0;j=n-1;
while(j-i>2){ //二分查找
mid = (i+j)>>1;
if(number>=p[mid]){
i=mid;
}else{
j=mid-1;
}
}
for(i=j;i>=0;i--){ //顺序查找
if(number>=p[i]){
break;
}
}
cost = number*q[i];
if(i<n-1 && cost>min[i+1]){
cost = min[i+1];
}
printf("%I64d\n",cost);
}
}