1. 程式人生 > >牛客網NOIP賽前集訓營-普及組(第七場) B 供給和需求

牛客網NOIP賽前集訓營-普及組(第七場) B 供給和需求

題目連結: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;
}