3969: [WF2013]Low Power

题目:

有n个机器,每个机器有2个芯片,每个芯片可以放k个电池。
每个芯片能量是k个电池的能量的最小值。
两个芯片的能量之差越小,这个机器就工作的越好。
现在有2nk个电池,已知它们的能量,我们要把它们放在n个机器上的芯片上,
使得所有机器的能量之差的最大值最小。

这道题让我因为题意卡了很久很久。。。。

首先排序电池,然后二分答案x,

判断过程:其实对一台机器有影响的只有两个芯片上的最小值,所以我们只要枚举(相邻的肯定最优)相邻的两个电池,只要它们的差小于枚举的x,就可以给一个机器来奠定基础啦!(其实就指他们两个能成为这台机器中两块芯片上的最小值,且符合x),那么我们需要找到符合x的n对芯片,这样才能成为n台机器(能找就找,)。好了,有了架子以后,因为每台机器需要2k个芯片,那么我们就需要判断,是否每个架子都能够有值比最小电池要大的2k-2个电池来填充。(具体判断会注释在程序里)。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int num,n,k,lef,righ,mid,ans,a[2000000];
bool b[2000000];
bool check(int x)
{
    int p=0,i=1,tot=0,t=0;
    t=0;
    tot=0;
    a[num+1]=-1;
  for (i=1;i<=num;i++) b[i]=true;
  for (i=1;i<=num-1;i++)//判断是否有符合x的n台机器。 
  if ((b[i])&&(a[i+1]-a[i]<=x)&&(t<n))
  {
      b[i]=false;
      b[i+1]=false;
      t+=1;
  }
  if (t<n) return false;//如果没有n台就退出
  p=0;
  for (int i=num;i>=1;i--)//从大到小枚举没被做架子的电池
  if  (b[i]) tot+=1;//记录当前有几块没被做架子的电池
  else 
  {
      p+=1;//记录有几块被做成架子的电池
      if (tot<p*(k-1)) return false;//如果后面较大(即大于最小值的电池,填进去才不会使最小值改变)的多余的电池数量不够填满机器,那么这台机器,就没法放满电池,
情况不符合x。
} return true; } int main() { cin>>n>>k; num=2*k*n; for (int i=1;i<=num;i++) cin>>a[i]; sort(a+1,a+1+num); lef=0; righ=a[num]-a[1]; while (lef<=righ) { mid=(lef+righ)/2; if (check(mid)) { ans=mid; righ=mid-1; } else lef=mid+1; } cout<<ans<<endl; return 0; }

ps:因为程序有些繁琐,所以容易超时。

原文地址:https://www.cnblogs.com/2014nhc/p/6201580.html