Epidemic in Monstropolis( Codeforces Round 378 (Div. 2) )

Epidemic in Monstropolis( Codeforces Round 378 (Div. 2) )

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 a_i.

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:

  1. the first monster can’t eat the second monster because a1 = 1 is not greater than a2 = 2;
  2. the second monster can’t eat the third monster because a2 = 2 is not greater than a3 = 2;
  3. the second monster can’t eat the fifth monster because they are not neighbors;
  4. 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 b**j. 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, …, a**n (1 ≤ a**i ≤ 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, …, b**k (1 ≤ b**j ≤ 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

61 2 2 2 1 225 5

Output

YES2 L1 R4 L3 L

Input

51 2 3 4 5115

Output

YES5 L4 L3 L2 L

Input

51 1 1 3 332 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.

题目大意

在Monstropolis城市爆发了疫情,所有的怪物都生病了。为了康复,所有怪物排队等待去看唯一的医生。由于饥饿,怪物开始相互吞噬。一个怪物可以吃掉相邻的怪物,如果它的体重大于被吞噬怪物的体重,并且它们在队列中是相邻的。每次吃掉一个怪物后,体重大幅增加,被吞噬的怪物就从队列中消失,队列长度减少1。

在一些时间后,所有怪物都康复,队列变成了另外一种样子。我们的任务是判断:通过怪物们的吃掉操作,是否可以从初始队列变到最终队列,并输出一个可行的吃掉顺序。如果无法得到最终队列,则输出 “NO”。

解题思路

  1. 理解操作规则

    • 一开始有 n 个怪物,每个怪物有一定的体重。
    • 之后,某些怪物可能会吃掉相邻的怪物,体重大幅增加。每次吃掉一个怪物时,体重增加,被吃掉的怪物从队列中消失。
    • 目标是通过一系列的吃掉操作,将初始队列变成最终队列。
  2. 关键观察

    • 由于只有相邻的怪物可以吃掉,且吃掉后体重增加,因此必须有体重大于相邻怪物的怪物才能执行吃掉操作。
    • 每次操作后,队列长度减少,体重变化,且队列的位置也会发生变化。
  3. 如何判断是否可能

    • 通过观察最终队列的每个怪物,能否从初始队列中找到对应的怪物,并判断它们是否通过一系列合法的吃掉操作从初始队列生成。
    • 如果能够通过模拟操作得到最终队列,则输出 YES 和操作序列;否则输出 NO。
  4. 模拟过程

    • 遍历初始队列,检查哪些怪物可以通过吃掉操作合并到目标队列中。每次找到符合条件的怪物后,模拟它们吃掉邻近怪物的过程,直到得到最终队列。
  5. 如何优化

    • 模拟过程中要注意避免重复操作,并且实时更新队列的状态,确保每一步都符合条件。

代码分析

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define endl '\n'
#define int long long
#define Max(a, b) (((a) > (b)) ? (a) : (b))
#define Min(a, b) (((a) < (b)) ? (a) : (b))
#define BoBoowen ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using namespace std;

const int inf = 1e9 + 7;
const int N = 2e5 + 10;
int a[N], sum[N];
int ans[N];
vector<string> answer;

struct Node
{
    int l, r;
} node[N];

int check(int l, int r)
{
    if (l == r)
    {
        return 1;
    }
    int maxx = 0;
    for (int i = l; i <= r; i++)
    {
        maxx = max(maxx, a[i]);
    }
    for (int i = l; i <= r; i++)
    {
        if (a[i] == maxx && i == l && a[i] > a[i + 1])
        {
            return 1;
        }
        else if (a[i] == maxx && i == r && a[i] > a[i - 1])
        {
            return 1;
        }
        else if (l != i && r != i && a[i] == maxx && (a[i] > a[i + 1] || a[i] > a[i - 1]))
        {
            return 1;
        }
    }
    return 0;
}

void dfs(int l, int len, int n)
{
    int maxx = 0;
    for (int i = l; i <= l + len - 1; i++)
    {
        maxx = max(maxx, a[i]);
    }
    while (len != 1)
    {
        for (int i = l; i <= l + len - 1; i++)
        {
            if (i == l && a[i] >= maxx && a[i] > a[i + 1])
            {
                string s = to_string(i) + " R";
                answer.push_back(s);
                a[i] += a[i + 1];
                maxx = max(maxx, a[i]);
                for (int j = i + 1; j <= n; j++)
                {
                    a[j] = a[j + 1];
                }
                break;
            }
            if (i == l + len - 1 && a[i] >= maxx && a[i] > a[i - 1])
            {
                string s = to_string(i) + " L";
                answer.push_back(s);
                a[i - 1] += a[i];
                maxx = max(a[i - 1], maxx);
                for (int j = i; j <= n; j++)
                {
                    a[j] = a[j + 1];
                }
                break;
            }
            if (i != l + len - 1 && i != l && a[i] >= maxx && a[i] > a[i + 1])
            {
                string s = to_string(i) + " R";
                answer.push_back(s);
                a[i] += a[i + 1];
                maxx = max(a[i], maxx);
                for (int j = i + 1; j <= n; j++)
                {
                    a[j] = a[j + 1];
                }
                break;
            }
            if (i != l + len - 1 && i != l && a[i] >= maxx && a[i] > a[i - 1])
            {
                string s = to_string(i) + " L";
                answer.push_back(s);
                a[i - 1] += a[i];
                maxx = max(a[i - 1], maxx);
                for (int j = i; j <= n; j++)
                {
                    a[j] = a[j + 1];
                }
                break;
            }
        }
        len--;
    }
}

void solved()
{
    int n, m;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        sum[i] = sum[i - 1] + a[i];
    }
    cin >> m;
    for (int i = 1; i <= m; i++)
    {
        cin >> ans[i];
    }
    int pre = 0;
    int hh = 0;
    for (int i = 1; i <= m; i++)
    {
        for (int j = pre + 1; j <= n; j++)
        {
            if (sum[j] - sum[pre] == ans[i])
            {
                node[hh].l = pre + 1;
                node[hh].r = j;
                pre = j;
                hh++;
                break;
            }
        }
    }
    if (hh != m || node[hh - 1].r != n)
    {
        cout << "NO";
        return;
    }
    for (int i = 0; i < hh; i++)
    {
        if (check(node[i].l, node[i].r) == 0)
        {
            cout << "NO";
            return;
        }
    }
    cout << "YES" << endl;
    for (int i = 0; i < m; i++)
    {
        dfs(i + 1, node[i].r - node[i].l + 1, n);
    }

    for (auto it : answer)
    {
        cout << it << endl;
    }
}

signed main()
{
    BoBoowen;

    int T = 1;
    while (T--)
    {
        solved();
    }
}

代码分析

  1. 输入处理

    • 读取初始队列 a 和最终队列 b 的体重。
  2. 核心逻辑

    • 使用递归 dfs 来模拟怪物之间的吃掉操作。每次操作时,找出能够吃掉邻近怪物的怪物,更新体重并将被吃掉的怪物移除。
  3. 检查是否可行

    • 通过 check 函数判断在某个区间是否符合吃掉的条件,即是否可以将当前的怪物吃掉并合并到目标队列中。
  4. 输出

    • 如果能够模拟得到目标队列,输出 “YES” 和具体的吃掉操作。如果无法得到目标队列,则输出 “NO”。

总结

通过模拟怪物吃掉操作并检查每一步的合法性,最终确定是否可以通过一系列操作将初始队列变为目标队列。代码主要通过递归模拟过程,并实时更新队列的状态。

你可能感兴趣的:(acm训练集合,模拟,双指针,贪心)