Atcoder beginner contest 166(ABC166) F题解

本文介绍了一种使用贪心策略解决特定数值操作问题的方法。通过比较两个数值大小并进行相应增减操作,确保了操作序列的有效性和目标达成的可能性。文章详细阐述了算法的实现过程,包括对各种边界条件的处理,以及如何通过预判未来操作来优化当前选择,避免数值变为负数。代码示例清晰展示了算法的具体实现。

F

思路: 考虑贪心。

例如,现在我们要操作的那两个数是A,B,我们这么搞:
①若A>B,则让A减一,B加一;
②若A<B,则让A加一,B减一。
上面两个操作很好理解,解释略。

③若A=B:
(1)若下一次操作涉及到A,那么A加一B减一;这样可以让下一步的AAA减成负数的概率更小;
(2)若下一次操作涉及到B,那么A减一B加一;这样可以让下一步的BBB减成负数的概率更小。
容易发现,(1)(2)这两种小类至少包含一种;但是可能同时出现(1)(2)这两种情况,那么就需要写个else而不是两个单纯的if。

直接模拟即可。注意不要粗心

时间复杂度: O(n)O(n)O(n)

#include <bits/stdc++.h>
#define int long long
using namespace std;
 
int n,a,b,c;
char ga[100005][5],ans[100005];
 
signed main()
{
	cin>>n>>a>>b>>c;
	for (int i=1;i<=n;i++)  cin>>ga[i][1]>>ga[i][2];
	
	for (int i=1;i<=n;i++)
	{
		if (ga[i][1]=='A'&&ga[i][2]=='B')
		{
			if (a<b)
			{
				a++,b--;
				ans[i]='A';
			}
			else if (a>b)
			{
				a--,b++;
				ans[i]='B';
			}
			else if (a==b)
			{
				if (ga[i+1][1]=='A'||ga[i+1][2]=='A')
				{
					a++,b--;
					ans[i]='A';
				}
				else
				{
					a--,b++;
					ans[i]='B';
				}
			}
		}
		if (ga[i][1]=='A'&&ga[i][2]=='C')
		{
			if (a<c)
			{
				a++,c--;
				ans[i]='A';
			}
			else if (a>c)
			{
				a--,c++;
				ans[i]='C';
			}
			else if (a==c)
			{
				if (ga[i+1][1]=='A'||ga[i+1][2]=='A')
				{
					a++,c--;
					ans[i]='A';
				}
				else
				{
					a--,c++;
					ans[i]='C';
				}
			}
		}
		if (ga[i][1]=='B'&&ga[i][2]=='C')
		{
			if (b<c)
			{
				b++,c--;
				ans[i]='B';
			}
			else if (b>c)
			{
				b--,c++;
				ans[i]='C';
			}
			else if (b==c)
			{
				if (ga[i+1][1]=='B'||ga[i+1][2]=='B')
				{
					b++,c--;
					ans[i]='B';
				}
				else
				{
					b--,c++;
					ans[i]='C';
				}
			}
		}
		if (a<0||b<0||c<0)  return cout<<"No"<<endl,0;
	}
	cout<<"Yes"<<endl;
	for (int i=1;i<=n;i++)  cout<<ans[i]<<endl;

	return 0;
}

撒花✿✿ヽ(°▽°)ノ✿撒花

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值