牛客網NOIP賽前集訓營-普及組(第七場) B 供給和需求
阿新 • • 發佈:2018-11-04
題目連結:https://www.nowcoder.com/acm/contest/171/B
剛開始忘記了需求量必須大於等於零。以為就是總需求是遞減,總供給是遞增,找二者最小值,錯了兩次。(_)
對於每一個買家有兩個引數a和b:當價格為0時,這個買家的需求量為a,每當價格提高1時,需求量會減少b。(當然,需求量不可能是負數,因此最多降為0)
當然本題的解決方法是二分,以零為左極限,以總商品需求量不為零的最大價格為右極限,在此區間二分找合適的值,然後進行特判,如果價格大於它們需求量為零的最大價格,那麼需求量為零。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include<algorithm> #include<iostream> #include<queue> using namespace std; long long a[100009],b[100009],c,ans[100009],n,sum3; long long chuli(long long m) { long long sum,i; sum=0; for(i=0;i<n;i++) { if(m>ans[i]); else { sum+=a[i]-m*b[i]; } } sum=sum-sum3*m; return sum; } int main() { long long m,sum1,sum2,ans1,ans2,ans3,i,minn,r,l,mid,maxn,x; scanf("%lld%lld",&n,&m); sum1=sum2=sum3=0; maxn=0; for(i=0;i<n;i++) { scanf("%lld%lld",&a[i],&b[i]); ans[i]=a[i]/b[i];///記錄所能需求大於等於零的最大價格 if(maxn<ans[i]) maxn=ans[i]; } for(i=0;i<m;i++) { scanf("%lld",&c); sum3+=c; } l=0;r=maxn; while(l<=r) { mid=(l+r)/2; x=chuli(mid); if(x==0) { printf("0\n"); return 0; } if(x<0) r=mid-1; else l=mid+1; } ans1=fabs(chuli(l)); ans2=fabs(chuli(l+1)); ans3=fabs(chuli(l-1)); minn=min(min(ans1,ans2),ans3); printf("%lld\n",minn); return 0; }