给你n个数字排成一个队列a,每个数字可以吃掉比自己两边相邻的比自己小的数字,吃完一个数字后整个队列位于该数字之后的会集体向前前进一个。之后给你k个数字组成一个队列b,问你是否有可能让n个数字进行多次相互吞吃之后形成这个队列b。
分析:
当时刚做完第二题看第三题才这么点人过,人数居然比第四题还少很吃惊,结果发现第四题的坑果然比第三题少多了。解法很简单,你遍历k个数字组成的队列b,如果能通过数字吞吃形成这个队列,那么在队列a中必定存在前i个数字相互吞吃能够形成b1,i由你自己计算。换句话说,队列b把a中n个数字分成了k份,每一份都能够组成队列b中的一个元素,从而形成k个元素的队列b。
那么要做的就很简单了,开个循环遍历b,在循环里再遍历a即可。做法很简单但是敲起来倒不短,wa了不少次。
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define INF 0x3f3f3f3f
const long long N=505;
const long long mod=1e9;
const double PI=acos(-1.0);
typedef long long ll;
int a[N],b[N];
int main() {
int n,k;
while (cin>>n) {
long long x=0,y=0;
for (int i=1; i<=n; i++) {
scanf("%d",&a[i]);
y+=a[i];
}
cin>>k;
for (int i=1; i<=k; i++) {
scanf("%d",&b[i]);
x+=b[i];
}
if (x!=y) {
cout<<"NO\n";
continue;
}
int flag=0,cur=1,temp=0,sssr=0;
for (int i=1; i<=k; i++) {
temp=0;
flag=cur;
while (temp<b[i]) {
temp+=a[cur];
cur++;
// cout<<temp<<endl;
}
if (temp!=b[i]) {
sssr=1;
break;
}
int ssr=0;
if (cur-flag==1) {
ssr=1;
}
for (int j=flag+1; j<cur; j++) {
if (a[j]!=a[flag]) {
ssr=1;
break;
}
}
if (ssr==0) {
sssr=1;
break;
}
}
if (sssr==1) {
cout<<"NO\n";
continue;
} else {
cout<<"YES\n";
cur=1;
int sum=0;
for (int i=1; i<=k; i++) {
temp=0;
flag=cur;
while (temp<b[i]) {
temp+=a[cur];
cur++;
}
int pos=flag,maxx=a[flag];
for (int j=flag+1; j<cur; j++) {
if (a[j]>maxx) {
maxx=a[j];
pos=j;
}
}
int en=1;
if (pos!=flag) {
for (int j=pos; j>flag; j--) {
en++;
printf("%d L\n",j-sum);
}
for (int j=0; j<cur-flag-en; j++) {
printf("%d R\n",flag-sum);
}
} else {
for (int j=flag+1; j<cur-1; j++) {
if (a[j]>=maxx&&a[j]>a[j+1]) {
pos=j;
}
}
for (int j=pos; j<cur-1; j++) {
printf("%d R\n",pos-sum);
}
en--;
for (int j=pos; j>flag; j--) {
printf("%d L\n",pos-en-sum);
en++;
}
}
sum+=cur-1-flag;
}
}
}
return 0;
}