zoukankan      html  css  js  c++  java
  • 【t101】小明搬家

    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

    小明要搬家了,大家都来帮忙。
    小明现在住在第N楼,总共K个人要把X个大箱子搬上N楼。
    最开始X个箱子都在1楼,但是经过一段混乱的搬运已经乱掉了。最后大家发现这样混乱地搬运过程效率太低了,于是总结出了提高
    效率的方法。
    大家的速度都是每分钟上(或下)一层楼。所有向上走的人手中都拿一个箱子,所有向下走的人都不拿箱子。到达第N层立刻放下箱
    子向下走,到达第一层立刻拿起箱子向上走。当一个人向上走,另一个向下走而在楼道里相遇时,向上走的人将手中的箱子交
    给另一个人,两人同时反向。即原来拿箱子向上走的人不拿箱子向下走,原来不拿箱子向下走的人现拿着箱子向上走。 【数据范围】
    对于30%的数据有K≤100,M≤100;
    对于60%的数据有K≤1000,M≤109;
    对于100%的数据有K≤500000,M≤109

    【输入格式】

    第一行N(N≤10^9),K(K≤500000),M(M≤10^9)分别表示楼层数、人数、还放在一楼地上的箱子数。
    接下来K行,每行两个数Ai,Bi。
    Ai表示第i人现在所在的层数,Bi为0或1,为0表示第i人正拿着箱子向上走,为1表示第i人不拿箱子向下走。
    输入满足没有任意两人正在同一楼层,在第一层的人一定正拿着箱子向上走,在第N层的人一定正不拿箱子向下走。
    【输出格式】

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

    Sample Input

    5 2 4
    1 0
    3 0

    Sample Output

    20

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=t101

    【题意】

    【题解】

    考虑一下两个人相遇的情况;
    必然是有一个人拿着一个箱子往上走;另外一个人空着手往下走;
    之后他们交换了箱子,然后各自转身;
    其实这个过程就相当于一个人能够穿过另外一个人往前走;
    根本没有想象的那么复杂;
    (拿箱子的人往上走,穿过那个空着手往下走的人;然后那个空着手往下走的人也空着手穿过那个往上走的人;都互相穿过了);
    那么也就是说每个人的行动都是独立的;
    所以可以一个人一个人地考虑
    这个时候我们就可以建立一个一维的坐标了;
    考虑从下往上走的人由低到高从左往右放置;
    考虑从上往下走的人,严格比往上走的人右,然后从高到低,也是从左往右地放;
    然后看看m%k等于多少;
    如果为0的话;
    则每个人再拿m/k个箱子;
    最后到达顶端的人所用的时间就是总时间;
    则肯定是坐标轴上最左边的那个人了;
    如果m%k不等于0;
    就说明箱子不够每个人分一样多;
    那么从右往左数m%k个人的范围内每个人都多拿一个箱子;
    则取从右往左数第m%k个人;
    它肯定是最后到的;
    也即由他决定最后的时间;当然此时他要再拿的箱子数为m/k + 1;
    然后模拟这个special的人它拿箱子的过程就好,求出最后的时间,也就是答案了.
    (程序中的坐标轴我转了个方向,也就是和上面的题解的方向相反了,这样好处理一点,当然坐标轴你要写个排序才能搞出来)

    【完整代码】

    #include<cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%I64d",&x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    const int K = 5e5+100;
    
    struct abc
    {
        LL now;
        int p;
    };
    
    LL n,m;
    int k;
    abc ren[K];
    
    bool cmp(abc a,abc b)
    {
        if (a.p!=b.p)
            return a.p > b.p;
        else
        {
            int t = a.p;
            if (t==0)
                return a.now > b.now;
            else
                return a.now < b.now;
        }
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        rel(n),rei(k),rel(m);
        rep1(i,1,k)
            rel(ren[i].now),rei(ren[i].p);
        sort(ren+1,ren+1+k,cmp);
        LL t = m % k;
        if (t==0) t = k;
        abc sp = ren[t];
        LL need = m/k;
        if (t!=k) need++;
        int p = sp.p;
        LL cost;
        if (p==0)
            cost = n-sp.now+n-1;
        else
            cost = sp.now-1;
        cost += 1LL*(2*(need-1)+1)*(n-1);
        cout << cost << endl;
        return 0;
    }
  • 相关阅读:
    [原创]c#快速排序类 Virus
    [原创]关系,依赖, Virus
    [原创]外包 Virus
    [原创]异步调用I/O方法的使用 Virus
    [原创]一个查找并且替换的算法 Virus
    封装原来的DirectoryInfo类,添加事件,可以代替FileSystemWatcher 类 Virus
    [原创]包头人在北京<一> Virus
    [原创]异步调用,多线程,委托 Virus
    [原创]异步,跨线程,非阻塞,DNS,Socket Virus
    [原创]大家动脑吧,一个面试题 Virus
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626613.html
Copyright © 2011-2022 走看看