給你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;
}