ZOJ 3676 Edward's Cola Plan

来源:互联网 发布:ie11浏览器mac 编辑:程序博客网 时间:2024/05/29 02:01

关于题意的分析就转一下大牛的了~~

不过这道题真的就是在考读题,其他都没什么好做的= =!!!不过我太菜了,A了快一个小时才A出来,郁闷啊

题意:你给第i个人喝普通可乐他能给你Pi个盖子,给他中奖可乐他能给你Qi个盖子。中奖可乐用M个盖子可以换一个,盖子可以先借用再去换可乐。问:最多能获得盖子数。


思路:按Qi-Pi差值排序。临界点是Qi-Pi=M,这时候换不换中奖可乐,最后得到的盖子是一样的。所以二分下临界点的位置。然后答案就是临界点之前的Pi求和+临界点之后Qi-M求和。
#include <stdio.h>#include <string.h>#include <string>#include <iostream>#include <algorithm>using namespace std;struct person{int pi,qi;int cha;bool operator < (person a)const{return a.cha>cha;}bool operator <(int a)const{return a<cha;}}per[100005];int sumpi[100005],sumqi[100005];bool cmp(person a,person b){return a.cha<b.cha;}int main(){int m,n;while(scanf("%d%d",&m,&n)!=EOF){memset(sumpi,0,sizeof(sumpi));memset(sumqi,0,sizeof(sumqi));for(int i=0;i<m;i++){scanf("%d%d",&per[i].pi,&per[i].qi);per[i].cha=per[i].qi-per[i].pi;}sort(per,per+m,cmp);int M;sumpi[0]=per[0].pi;sumqi[0]=per[0].qi;for(int i=1;i<m;i++){sumpi[i]=sumpi[i-1]+per[i].pi;sumqi[i]=sumqi[i-1]+per[i].qi;}int ans=-1;for(int i=0;i<n;i++){scanf("%d",&M);//int l=0,r=m;/*int mm=(l+r)/2;if(per[mm].cha>M) r=mm-1;典型的彩笔敲的二分,大错特错!! if(per[mm].cha<M) l=mm+1;if(per[mm].cha==M){ ans=mm; break;}}if(ans==-1) printf("error\n");else printf("%d\n",sumpi[ans]+(sumqi[m]-sumqi[ans]-m*(m-ans)));//注意临界值!!!很重要 *///ans=lower_bound(per,per+m,M)-per;   int l = 0, r = m, ans = -1;        while (l <= r)        {            int mm = (l + r) / 2;            if (per[mm].cha < M) l = mm + 1;//这个就当二分模板把             else            {                ans = mm; r = mm - 1;            }        }if(ans==-1) printf("%d\n",sumpi[m-1]);else printf("%d\n",sumpi[ans-1]+(sumqi[m-1]-sumqi[ans-1]-M*(m-ans)));}}} 


原创粉丝点击