小明搬家

小明搬家

【问题描述】
小明要搬家了,大家都来帮忙。
小明现在住在第N楼,总共K个人要把X个大箱子搬上N楼。
最开始X个箱子都在1楼,但是经过一段混乱的搬运已经乱掉了。最后大家发现这样混乱地搬运过程效率太低了,于是总结出了提高效率的方法。
大家的速度都是每分钟上(或下)一层楼。所有向上走的人手中都拿一个箱子,所有向下走的人手中都不拿箱子。到达第N层立刻放下箱子向下走,到达第1层立刻拿起箱子向上走。当一个人向上走,另一人向下走而在楼道里相遇时,向上走的人将手中的箱子交给另一人,两人同时反向。即原来拿箱子向上走的人不拿箱子向下走,原来不拿箱子向下走的人现拿着箱子向上走。
求将所有箱子搬完所需的最短时间。
【输入】
第一行N(N≤10^9),K(K≤500000),M(M≤10^9),分别表示楼层数、人数、还放在一楼地上的箱子数。
接下来K行,每行两个数Ai,Bi。
Ai表示第i人现所在的楼层数,Bi为0或1,为0表示第i人正拿着箱子向上走,为1表示第i人不拿箱子向下走。
输入满足没有任意两人正在同一楼层,在第1层的人一定正拿着箱子向上走,在第N层的人一定正不拿箱子向下走。

一开始看在不停的思考数学:
都是奇数或者偶数楼梯的人可以传递……然后想了很久发现没什么用
因为这道题 思想其实很简单
每一个位于一楼上的盒子,都是要2*(n-1)的时间的,因为无论如何,无论是否传递,都要一个人上去到顶层一个人下来拿箱子——>传递=越过
然后位于一楼的箱子所有箱子所需要的时间即为:(m/k)*(n-1)*2(每一个人每一时刻都在走动所以要除)
然后那些已经在楼梯上的箱子则是需要最久的搬运
所以再加上一个pe[m%k]

程序如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int pe[500010],cnt;
long long n,k,m;
int main()
{
freopen("box.in","r",stdin);
freopen("box.out","w",stdout);
  int i,a,b;
  cin>>n>>k>>m;
  for (i=1;i<=k;i++)
   {
      scanf("%d%d",&a,&b);
      if (b==0) pe[++cnt]=n-a;
      else pe[++cnt]=a-n;
   }
   sort(pe+1,pe+k+1);
   pe[0]=pe[k];
   cout<<(m/k)*(n-1)*2+pe[m%k];//必定有 (m/k)*(n-1)*2个路程要走的 再加上余下的 
}

猜你喜欢

转载自blog.csdn.net/beautiful_cxw/article/details/80960227