CF379B New Year Present题解

该博客主要探讨了一个机器人在最左边开始,每次可以向左或向右移动并放置硬币的问题。要求输出达到目标状态的任意一种行走方案。博主提出了一种解决方案:从头到尾或从尾到头进行尝试,并在每一步判断是否可以放硬币,同时注意不能连续两次投币。博主还提到了枚举次数的安全范围,并给出了C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目传送门

大体意思就是有一个机器人在最左边在放硬币,它每一次操作都可以选择向左移动一个单位或向右移动一个单位,也可以选择在它所在的位置放一枚硬币,要求的输出的是达到目标状态的任意一种方案。

思路

既然题目要求的是输出任意一种方案,那么我们只要保证达到目标状态就行了,多余的步骤是不会影响结果的。

我们就可以每一次都从头走到尾或从尾走到头,对于每一次从头走到尾,我们先判断能不能放硬币,然后再往右走,对于每一次从尾到头,我们也还是先判断能不能放硬币,然后再往左走,这样进行若干次后,机器人的步骤会一直重复,此时结束循环即可。

这里还有些细节需要我们注意,因为题目中要求机器人不能连续两次进行投币操作,所以我们在从头到尾进入从尾到头的操作或从尾到头进入从头到尾的操作时需要特判一下它上一步是否进行了投币操作,如果进行了投币操作,那么直接向左或向右走,否则先去判断是否可以投币然后再向左或向右走。

对于我们枚举从头到尾以及从尾到头的次数,题目中给出的 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;
	//完结撒花~~ 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值