NOIP第二轮模拟 Day2 小明搬家

【问题描述】

小明要搬家了,大家都来帮忙。
小明现在住在第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层的人一定正不拿箱子向下走。

【输出】

仅包含一个整数,为搬完箱子的时间。

【输入输出样例】

#1
5 2 4
1 0
4 0

#2
20


【分析】

不关心个人“当一个人向上走,另一人向下走而在楼道里相遇时,向上走的人将手中的箱子交给另一人,两人同时反向。”,可以看做仅仅是两人正常走过。如此不难看出2n-2步后,所有人会回到自己原来的位置,同时有k个箱子被放在n层,又有k个箱子在1层被拿走。

扫描二维码关注公众号,回复: 2390434 查看本文章

走完多次循环直至1层的箱子数小于k时开始模拟(虽然并不是完全暴力)。
如果1层箱子数为0,则再加上最下面一位抬箱子的人到n层的距离。
如果1层箱子数为d(d≠0),则算出所有人再从1层抱一个箱子的总距离,并排序加上第d大的距离。

下面附上代码一份;

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=500100;
long long n,k,m;
long long ans=0;
int a[maxn],b[maxn];
int main()
{
    freopen("box.in","r",stdin);
    freopen("box.out","w",stdout);
    ios::sync_with_stdio(false);
    cin>>n>>k>>m;
    for(int i=1;i<=k;i++)
        cin>>a[i]>>b[i];
    ans+=2*(m/k)*(n-1);
    m=m%k;
    if(m==0)
    {
        long long pos=n;
        for(int i=1;i<=k;i++)
            if(b[i]==0&&a[i]<pos)
                pos=a[i];
        ans+=(n-pos);
        cout<<ans<<endl;
    }
    else
    {
        for(int i=1;i<=k;i++)
            if(b[i]==1) a[i]=a[i]+n-2;
            else a[i]=3*n-a[i]-2;
        sort(a+1,a+k+1);
        ans+=a[m];
        cout<<ans<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xyc1719/article/details/80959085
今日推荐