牛客网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;
}

猜你喜欢

转载自blog.csdn.net/xiaoshazheng/article/details/83513574