zoukankan      html  css  js  c++  java
  • 【16.52%】【codeforces 733C】Epidemic in Monstropolis

    time limit per test1 second
    memory limit per test256 megabytes
    inputstandard input
    outputstandard output
    There was an epidemic in Monstropolis and all monsters became sick. To recover, all monsters lined up in queue for an appointment to the only doctor in the city.

    Soon, monsters became hungry and began to eat each other.

    One monster can eat other monster if its weight is strictly greater than the weight of the monster being eaten, and they stand in the queue next to each other. Monsters eat each other instantly. There are no monsters which are being eaten at the same moment. After the monster A eats the monster B, the weight of the monster A increases by the weight of the eaten monster B. In result of such eating the length of the queue decreases by one, all monsters after the eaten one step forward so that there is no empty places in the queue again. A monster can eat several monsters one after another. Initially there were n monsters in the queue, the i-th of which had weight ai.

    For example, if weights are [1, 2, 2, 2, 1, 2] (in order of queue, monsters are numbered from 1 to 6 from left to right) then some of the options are:

    the first monster can’t eat the second monster because a1 = 1 is not greater than a2 = 2;
    the second monster can’t eat the third monster because a2 = 2 is not greater than a3 = 2;
    the second monster can’t eat the fifth monster because they are not neighbors;
    the second monster can eat the first monster, the queue will be transformed to [3, 2, 2, 1, 2].
    After some time, someone said a good joke and all monsters recovered. At that moment there were k (k ≤ n) monsters in the queue, the j-th of which had weight bj. Both sequences (a and b) contain the weights of the monsters in the order from the first to the last.

    You are required to provide one of the possible orders of eating monsters which led to the current queue, or to determine that this could not happen. Assume that the doctor didn’t make any appointments while monsters were eating each other.

    Input
    The first line contains single integer n (1 ≤ n ≤ 500) — the number of monsters in the initial queue.

    The second line contains n integers a1, a2, …, an (1 ≤ ai ≤ 106) — the initial weights of the monsters.

    The third line contains single integer k (1 ≤ k ≤ n) — the number of monsters in the queue after the joke.

    The fourth line contains k integers b1, b2, …, bk (1 ≤ bj ≤ 5·108) — the weights of the monsters after the joke.

    Monsters are listed in the order from the beginning of the queue to the end.

    Output
    In case if no actions could lead to the final queue, print “NO” (without quotes) in the only line.

    Otherwise print “YES” (without quotes) in the first line. In the next n - k lines print actions in the chronological order. In each line print x — the index number of the monster in the current queue which eats and, separated by space, the symbol ‘L’ if the monster which stays the x-th in the queue eats the monster in front of him, or ‘R’ if the monster which stays the x-th in the queue eats the monster behind him. After each eating the queue is enumerated again.

    When one monster eats another the queue decreases. If there are several answers, print any of them.

    Examples
    input
    6
    1 2 2 2 1 2
    2
    5 5
    output
    YES
    2 L
    1 R
    4 L
    3 L
    input
    5
    1 2 3 4 5
    1
    15
    output
    YES
    5 L
    4 L
    3 L
    2 L
    input
    5
    1 1 1 3 3
    3
    2 1 6
    output
    NO
    Note
    In the first example, initially there were n = 6 monsters, their weights are [1, 2, 2, 2, 1, 2] (in order of queue from the first monster to the last monster). The final queue should be [5, 5]. The following sequence of eatings leads to the final queue:

    the second monster eats the monster to the left (i.e. the first monster), queue becomes [3, 2, 2, 1, 2];
    the first monster (note, it was the second on the previous step) eats the monster to the right (i.e. the second monster), queue becomes [5, 2, 1, 2];
    the fourth monster eats the mosnter to the left (i.e. the third monster), queue becomes [5, 2, 3];
    the finally, the third monster eats the monster to the left (i.e. the second monster), queue becomes [5, 5].
    Note that for each step the output contains numbers of the monsters in their current order in the queue.

    【题解】

    贪心.
    最后的目标序列是按顺序给的;
    则我们要达到的目标也应该是顺序的;
    则我们枚举当前要达到哪一个目标i(i=1..k)
    然后从在a[i..j]里面找一个最大值mx;其中a[i]+a[i+1]+..+a[j]==bi;
    就一直用这个最大值往左往右吃(因为是最大的,所以i..j这个范围内只要再吃一只就全都能吃了,当然如果a[i]..a[j]全都是相同的值则无解);
    吃掉之后把数组整个左移就好;
    数据的第13个点坑的是如果最后的序列两个序列的长度不同也是算作无解的;

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <set>
    #include <map>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <string>
    #define lson L,m,rt<<1
    #define rson m+1,R,rt<<1|1
    #define LL long long
    
    using namespace std;
    
    const int MAXN = 600;
    const int dx[5] = {0,1,-1,0,0};
    const int dy[5] = {0,0,0,-1,1};
    const double pi = acos(-1.0);
    
    int n,a[MAXN],k,b[MAXN];
    vector < pair<int,char> > v;
    
    void input_LL(LL &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t) && t!='-') t = getchar();
        LL sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    void input_int(int &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t)&&t!='-') t = getchar();
        int sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    void TAT()
    {
        puts("NO");
        exit(0);
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        input_int(n);
        for (int i = 1;i <= n;i++)
            input_int(a[i]);
        input_int(k);
        for (int i = 1;i <= k;i++)
            input_int(b[i]);
        for (int i = 1;i <= k;i++)
        {
            while (a[i]!=b[i])
            {
                if (a[i] > b[i])
                    TAT();
                int sum = 0,mx = 0;
                int j = i;
                while (j <= n && sum < b[i])
                    mx = max(mx,a[j]),sum+=a[j],j++;
                bool flag = 0;
                for (int l = i;l<=n;l++)
                    if (a[l]==mx && l-1>=i && a[l-1]!=mx)
                    {
                        flag = 1;
                        a[l-1]+=a[l];
                        v.push_back(make_pair(l,'L'));
                        for (int t = l;t<=n-1;t++)
                            a[t] = a[t+1];
                        n--;
                        break;
                    }
                    else
                        if (a[l]==mx && (l+1)<=n && a[l+1]!=mx)
                        {
                            flag = 1;
                            a[l]+=a[l+1];
                            v.push_back(make_pair(l,'R'));
                            for (int t = l+1;t<=n-1;t++)
                                a[t]=a[t+1];
                            n--;
                            break;
                        }
                if (!flag)
                    TAT();
            }
        }
        if (n!=k)
            TAT();
        puts("YES");
        int len = v.size();
        for (int i = 0;i <= len-1;i++)
            printf("%d %c
    ",v[i].first,v[i].second);
        return 0;
    }
  • 相关阅读:
    【队列应用一】随机迷宫|随机起点终点*最短路径算法
    【堆栈应用二】迷宫算法,可直接动态运行
    【堆栈应用一】一个数divided=几个最小质因数的乘积(时间复杂度On)
    MyEclipse2014中Java类右键Run as没有JUnit Test
    C++中break/Continue,exit/return的理解
    windows下用C++修改本机IP地址
    windows下注册表的操作
    详解Java的Spring框架中的注解的用法
    什么是Java Bean
    JS windows对象的top属性
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632094.html
Copyright © 2011-2022 走看看