题目传送门
大体意思就是有一个机器人在最左边在放硬币,它每一次操作都可以选择向左移动一个单位或向右移动一个单位,也可以选择在它所在的位置放一枚硬币,要求的输出的是达到目标状态的任意一种方案。
思路
既然题目要求的是输出任意一种方案,那么我们只要保证达到目标状态就行了,多余的步骤是不会影响结果的。
我们就可以每一次都从头走到尾或从尾走到头,对于每一次从头走到尾,我们先判断能不能放硬币,然后再往右走,对于每一次从尾到头,我们也还是先判断能不能放硬币,然后再往左走,这样进行若干次后,机器人的步骤会一直重复,此时结束循环即可。
这里还有些细节需要我们注意,因为题目中要求机器人不能连续两次进行投币操作,所以我们在从头到尾进入从尾到头的操作或从尾到头进入从头到尾的操作时需要特判一下它上一步是否进行了投币操作,如果进行了投币操作,那么直接向左或向右走,否则先去判断是否可以投币然后再向左或向右走。
对于我们枚举从头到尾以及从尾到头的次数,题目中给出的 n n n 最大到 300 300 300,给出的某一个地方的硬币数 a i a_i ai 最大到 300 300 300,所以我们没有必要去枚举一个特别大的数,可能还会出现误差,我们的枚举次数在 400 400 400 到 1000 1000 1000 之间最为安全。
总的来说,本题细节还是比较多的。
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,t,q,p;
int f[500];
void pre(int s)
{
while(t<=900){//安全的枚举次数
for(int i=s;i<=n;i++){
if(p==1&&i==s){
p=0;
cout<<'R';
continue;
//上一次的头放过,此次直接向右走
}
if(f[i]>0){
if(i==n)
q=1;//特判从尾到头的尾
f[i]--;//投币
cout<<"P";
}
if(i!=n)
cout<<"R";//到最右端,没必要在往右走
}
for(int i=n;i>=s;i--){
if(q==1&&i==n){
q=0;
cout<<'L';
continue;
//上一次的尾放过,此次直接向左走
}
if(f[i]>0){
if(i==s)
p=1;///特判从头到尾的头
f[i]--;//投币
cout<<"P";
}
if(i!=s)
cout<<"L";//到最左端,没必要在往左走
}
t++;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&f[i]);
pre(1);//从最左边开始
return 0;
//完结撒花~~
}