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:
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.
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.
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.
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
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:
Note that for each step the output contains numbers of the monsters in their current order in the queue.
在Monstropolis城市爆发了疫情,所有的怪物都生病了。为了康复,所有怪物排队等待去看唯一的医生。由于饥饿,怪物开始相互吞噬。一个怪物可以吃掉相邻的怪物,如果它的体重大于被吞噬怪物的体重,并且它们在队列中是相邻的。每次吃掉一个怪物后,体重大幅增加,被吞噬的怪物就从队列中消失,队列长度减少1。
在一些时间后,所有怪物都康复,队列变成了另外一种样子。我们的任务是判断:通过怪物们的吃掉操作,是否可以从初始队列变到最终队列,并输出一个可行的吃掉顺序。如果无法得到最终队列,则输出 “NO”。
理解操作规则:
n
个怪物,每个怪物有一定的体重。关键观察:
如何判断是否可能:
模拟过程:
如何优化:
#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();
}
}
输入处理:
a
和最终队列 b
的体重。核心逻辑:
dfs
来模拟怪物之间的吃掉操作。每次操作时,找出能够吃掉邻近怪物的怪物,更新体重并将被吃掉的怪物移除。检查是否可行:
check
函数判断在某个区间是否符合吃掉的条件,即是否可以将当前的怪物吃掉并合并到目标队列中。输出:
通过模拟怪物吃掉操作并检查每一步的合法性,最终确定是否可以通过一系列操作将初始队列变为目标队列。代码主要通过递归模拟过程,并实时更新队列的状态。