(easy version):

题目链接:http://codeforces.com/contest/1296/problem/E1

题目一句话就是说,两种颜色不同的字符可以相互换位,

问,对这字符串用最多两种颜色染色,然后经过有限次换位

可以变成字典序排序的顺序。

思路:一个字符需不需要换位,应该是参照最后的字典序的顺序,

那么,我们应该给字符串排序,再去思考问题。

我们知道,如果str[now_i]的位置和排序后的位置不一样,那就是需要换位。

我们还知道,如果str[now_i]的当前位置如果小于等于排序后的位置,

说明str[now_i]会往后移动,之前应该是会多出(>=0)个字符,那么我们不妨

让str[now_i]不主动移动(标记‘0’),让str[now_x]当前位置大于排序后位置的去向前主动移动(也必须向前移动)(标记‘1’),

那么经过一些str[now_x]向前移动,str[now_i]会被动的回到排序后的位置,从而达到"YES"。

那什么情况是“NO”?

如果我们标记的'1'字符组成的字符串出现了"ba",”bca”,就是说不满足非递减性质,

那么"ba",a是'1',b也是'1',就是说,a不可能到b前面,那也就是“NO”了,举个样例:

7
abcdedc

0000011

撇开这个样例不管,如果出现了"ba",如果把要b换成'0',那么之前本该属于b位置的需要变成'1',

使得可以和b转位,但是被换成'1'的那个字符又导致'a'不能回到a本该属于的位置,所以这个情况是''NO"就证明成立了,也间接证明了"YES"情况的正确性,所以方法猜想正确,之后的做法就只需要维护这个方法就行。

时间复杂度可以是O(n)

 #include <iostream>
#include <algorithm>
#include <string>
#include <queue>
#include <cstdio>
using namespace std; struct Info{
queue<int > index;
void pb(int x){ index.push(x); }
int loc(){ int x = index.front(); index.pop(); return x; }
}info[];//存储不同字符出现的位置 int main(){ string str;
int a[];
int col[];//颜色
int n;
cin >> n >> str;
for(int i = ; i < n;++i) a[i] = str[i]-'a';//字符转化为数字
sort(a,a+n);//排序
for(int i = ; i < n; ++i) info[a[i]].pb(i);//把该字符出现的位置记录
char error[] = "aa";//error[0]存储的是不需要主动移动的字符最大是哪个
//error[1]存储的是需要主动移动的字符最大的是哪个
for(int now = ; now < n; ++now){//now表示当前位置
int after = info[str[now]-'a'].loc();//取一个该字符排序后的位置
if(now <= after){//当前位置小于等于排序后的位置,这里有个特殊情况,
//abcdedc①
//abccdde
//可以看出第二个d虽然和排序后的位置一样,但是他需要换位
if(str[now] >= error[]){
error[] = str[now];
col[now] = ;
}else{
col[now] = ;
if(str[now] > error[]) error[] = str[now];//①的情况出现需要改变error[1]的字符
}
}
else{
if(str[now] >= error[]){
col[now] = ;
error[] = str[now];
}else{
error[] = '!'; break;
}
}
}
if(error[] == '!' || error[] == '!') cout << "NO\n";
else{
cout << "YES\n";
for(int i = ; i < n; ++i) cout << col[i];
cout << endl;
} return ;
}

(hard version):

题目链接:http://codeforces.com/contest/1296/problem/E2

题目:E1说明了只能用两种颜色去染色,现在是最少用几种颜色去染色,可以完成字典序排序。

思路:再次思考E1的证明情况,如果该字符需要染成'1',那么它们组成的字符串是“单调非递减”的,

而'0'组成的字符串也是“单调非递减”的。于是,我们想到,可以把这个题目抽象成一些数字组成一个序列,

问你该序列最少可以分成几个满足性质“非单调递减”的集合,也就是几种颜色了。

那么E2题目就变得简单了,E1也可以不那么复杂的写了。

最多26个字符,也就是最多26个集合,那么 时间复杂度是O(26*n)。

这里有个细节,我们需要充分利用字符之间的间隔,举个例子:

abacd...

先分成两个集合 :ab  ac,应该把d放在"ac"的后面,这样才能充分能利用字符之间的间隔,满足最少颜色。

 #include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std; const int N = (int)2e5+;
struct node{
int index;
char ch;
};
int col = ;//集合数
string str;//每个集合最后的字符
int ans[N]; int main(){ ios::sync_with_stdio(false);
cin.tie(); cout.tie();
int n;
char ch,max_ch,which_col,len,tmp_ch,now_ch;
cin >> n;
for(int i = ; i < n; ++i){
cin >> ch;
which_col = -;//选哪种颜色
tmp_ch = 'A';
for(int j = ; j < col; ++j){
now_ch = str[j];
//选col个集合中最后字符小于等于ch且最接近ch的
if(now_ch <= ch){
if(now_ch > tmp_ch){
tmp_ch = now_ch;
which_col = j;
}
}
}
if(which_col != -){
str[which_col] = ch;
ans[i] = which_col+;
}
else{
//需要新加一种颜色
str += ch;
++col;
ans[i] = col;
}
} cout << col << endl;
cout << ans[];
for(int i = ; i < n; ++i) cout << ' ' << ans[i];
cout << endl; return ;
}

Codeforces Round #617 (Div. 3) String Coloring(E1.E2)的更多相关文章

  1. Codeforces Round #378 (Div. 2) D题(data structure)解题报告

    题目地址 先简单的总结一下这次CF,前两道题非常的水,可是第一题又是因为自己想的不够周到而被Hack了一次(或许也应该感谢这个hack我的人,使我没有最后在赛后测试中WA).做到C题时看到题目情况非常 ...

  2. Codeforces Round #367 (Div. 2) A. Beru-taxi (水题)

    Beru-taxi 题目链接: http://codeforces.com/contest/706/problem/A Description Vasiliy lives at point (a, b ...

  3. Codeforces Round #603 (Div. 2) E. Editor(线段树)

    链接: https://codeforces.com/contest/1263/problem/E 题意: The development of a text editor is a hard pro ...

  4. Codeforces Round #515 (Div. 3) 解题报告(A~E)

    题目链接:http://codeforces.com/contest/1066 1066 A. Vova and Train 题意:Vova想坐火车从1点到L点,在路上v的整数倍的点上分布着灯笼,而在 ...

  5. Codeforces Round #222 (Div. 1) Maze —— dfs(连通块)

    题目链接:http://codeforces.com/problemset/problem/377/A 题解: 有tot个空格(输入时统计),把其中k个空格变为wall,问怎么变才能使得剩下的空格依然 ...

  6. Codeforces Round #336 (Div. 2) D. Zuma(区间DP)

    题目链接:https://codeforces.com/contest/608/problem/D 题意:给出n个宝石的颜色ci,现在有一个操作,就是子串的颜色是回文串的区间可以通过一次操作消去,问最 ...

  7. Codeforces Round #316 (Div. 2) C. Replacement(线段树)

    C. Replacement time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  8. Codeforces Round #305 (Div. 2) E题(数论+容斥原理)

    E. Mike and Foam time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  9. Codeforces Round #626 (Div. 2) D. Present(位运算)

    题意: 求n个数中两两和的异或. 思路: 逐位考虑,第k位只需考虑0~k-1位,可通过&(2k+1-1)得到一组新数. 将新数排序,当两数和在[2k,2k+1)和[2k+1+2k,2k+2)之 ...

随机推荐

  1. windows7下mysql8.0.18部署安装

    一.前期准备(windows7+mysql-8.0.18-winx64) 1.下载地址:https://dev.mysql.com/downloads/ 2.选择直接下载不登录账号,下载的压缩包大概两 ...

  2. 【题解】歌唱王国(概率生成函数+KMP)+伦讲的求方差

    [题解]歌唱王国(概率生成函数+KMP)+伦讲的求方差 生成函数的本质是什么呀!为什么和It-st一样神 设\(f_i\)表示填了\(i\)个时候停下来的概率,\(g_i\)是填了\(i\)个的时候不 ...

  3. MementoPattern(备忘录模式)-----Java/.Net

    备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象.备忘录模式属于行为型模式.

  4. 利用cuteftp上传并修改网站上内容

    1.下载cuteftp 2.在host中输入网址(如:219.142.121.2) 3.username中输入(如:BNULS) 4.passpord中输入:(如410teamgood) 5.端口输入 ...

  5. Go Goosy Disk Docker Port Provisioners(GDP)

    小伙伴们,她们中出了一个叛徒,他是谁?是谁?是谁? 由一则口口相传的故事开始吧: 中午吃饭时间抽空小李跑到同座大楼的小张公司串门,小李是一名docker顾问熟称砖家,这间公司老板想挖小李,他盯了前台不 ...

  6. UIChatBox模块示例demo

    感谢论坛版主 马浩川 的分享. UIChatBox 模块是一个聊天输入框模块,开发者可自定义该输入框的功能.通过 open 接口可在当前 window 底部打开一个输入框,该输入框的生命属于当前 wi ...

  7. 状态压缩 hdu #10

    You are playing CSGO. There are n Main Weapons and m Secondary Weapons in CSGO. You can only choose ...

  8. 自定义博客cnblogs样式的必备前端小知识——css

    css样式相关小知识 文字超出一行显示省略号 overflow: hidden; /*自动隐藏文字*/ text-overflow: ellipsis; /*文字隐藏后添加省略号*/ white-sp ...

  9. git 工作实用创建删除分支

    一.创建分支 .创建本地分支并切换 git checkout -b dev_wt2 .创建切换并关联远程分支 git checkout -b dev_wt3 orgin/dev_wt3 .创建远程分支 ...

  10. asp.net生成店铺推广二维码,二维码中间加logo(源码)

    二维条码比一维条码记载数据量更多,二维码条码是一种高密度.高信息含量的便携式数据文件,是实现证件及卡片等大容量.高可靠性信息自动存储.携带并可用机器自动识读的理想手段.而且可以记载更复杂的数据,比如图 ...