题目:
有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:因为程序有些繁琐,所以容易超时。