Atcoder beginner contest 166(ABC166) F题解

F

思路: 考虑贪心。

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

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

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

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

#include 
#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;
}

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

你可能感兴趣的:(比赛题解,数学)