CF1296E1——String Coloring (easy version)

原题

This is an easy version of the problem. The actual problems are different, but the easy version is almost a subtask of the hard version. Note that the constraints and the output format are different.
You are given a string ss consisting of nn lowercase Latin letters.
You have to color all its characters one of the two colors (each character to exactly one color, the same letters can be colored the same or different colors, i.e. you can choose exactly one color for each index in ss).
After coloring, you can swap any two neighboring characters of the string that are colored different colors. You can perform such an operation arbitrary (possibly, zero) number of times.
The goal is to make the string sorted, i.e. all characters should be in alphabetical order.
Your task is to say if it is possible to color the given string so that after coloring it can become sorted by some sequence of swaps. Note that you have to restore only coloring, not the sequence of swaps.InputThe first line of the input contains one integer nn (1≤n≤2001≤n≤200) — the length of ss.
The second line of the input contains the string ss consisting of exactly nn lowercase Latin letters.OutputIf it is impossible to color the given string so that after coloring it can become sorted by some sequence of swaps, print “NO” (without quotes) in the first line.
Otherwise, print “YES” in the first line and any correct coloring in the second line (the coloring is the string consisting of nn characters, the ii-th character should be ‘0’ if the ii-th character is colored the first color and ‘1’ otherwise).

题意简介

要求你用 0 1串表示一段字符串,如果相邻两位不同,那么这两位代表的字符可以进行交换
问是否存在一串01串进行有限次交换使得该字符串满足字典序。

思考

首先,我们需要思考01串交换的性质,熟悉01串的朋友可能一眼就看出来此题中的01串满足一个性质
0可以在连续为1的子串中游动,当遇到0时停止
举个例子:
001111->0<-1110
箭头指向的0满足这一条件向左可以运动到第3位,向右可以遇到倒数第二位;
同理1也如此
那么通过一系列变换后我们发现原子串等价于
一串连续的0+一串连续的1时,并且0和1的原下标均为递增

再进一步

我们需要考虑什么情况下,一串连续的0+一串连续的1,通过变换可以满足图中的条件?
答案很显然:
当0和1代表的子串不下降时;
那么算法很显然:
找出两段不下降的子数列

code:

#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
using namespace std;
char p[200010];
char s[200010];
int vis[200010];
int main(){
	int len;
	cin>>len;
	cin>>p+1;
	
	int so = 0;
	for(int i=1;i<=len;i++)
	{
		if(p[i]>=so){
			so = p[i] ;
			s[i] = '0';
			vis[i] = 1;
		}
	}
	so = 0;
	for(int i=1;i<=len;i++)
	{
		if(!vis[i] && p[i]>=so){
			so = p[i];
			s[i] = '1';
			vis[i] = 1;
		}
		if(!vis[i] && p[i]<so){
			cout<<"NO"<<endl;
			return 0;
		}
	}
	cout<<"YES"<<endl;
	for(int i=1;i<=len;i++)
	{
		cout<<s[i];
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值