(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. __FILE__,__LINE__,__DATE__,__TIME__,__FUNCTION__的使用

    C/C++ 有5个常用的预定义宏,可以当作变量直接使用 __FILE__,__FUNCTION __,__LINE__,__DATE__,__TIME__. 注意是两个下划线. 其含义如下: __FI ...

  2. Qt5 http/HTTPS访问 以及JSON解析的实用

    实用QT5访问HTTP/以及HTTPS协议访问 并且调用Json解析 #include "mywidget.h" #include "ui_mywidget.h" ...

  3. ruby 编写控制台进度条

    ruby 中,$stdout.flush 让控制台当前行内容可以重写,以此我们可以做出进度条的效果. def set_progress(index, char = '*') print (char * ...

  4. Win10下设置默认输入法与默认中文输入

    实现的效果: 把自己需要的一个或多个输入法软件添加到输入法列表中(一般就指定一个),避免了需要在打字时Ctrl + Shift等快捷键在多个输入法中不停切换的麻烦 首选语言默认为中文,毕竟作为一个中国 ...

  5. es snapshot备份到hdfs及从hdfs恢复snapshot

    snapshot可以将es整个集群,具体索引数据备份到磁盘,hdfs等.需要时,可以从磁盘,hdfs恢复数据到es. 具体参考: https://elasticsearch.cn/article/61 ...

  6. 输入n个学生,并且输入成绩,判断是否偏科

    H学校的领导主任决定分析一下今年所有N名学生的考试成绩,从中找出偏科的学生,考试成绩包含语文,数学,英语三门课程的分数,已知偏科的定义是:某一门课程的分数大于等于90,并且另外两门的分数小于等于70. ...

  7. 曹工说Spring Boot源码(9)-- Spring解析xml文件,到底从中得到了什么(context命名空间上)

    写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...

  8. 【一起学源码-微服务】Hystrix 源码一:Hystrix基础原理与Demo搭建

    说明 原创不易,如若转载 请标明来源! 欢迎关注本人微信公众号:壹枝花算不算浪漫 更多内容也可查看本人博客:一枝花算不算浪漫 前言 前情回顾 上一个系列文章讲解了Feign的源码,主要是Feign动态 ...

  9. C#调用7z实现文件的压缩与解压

    1.关于7z 首先在这里先介绍一下7z压缩软件,7z是一种主流的 压缩格式,它拥有极高的压缩比.在计算机科学中,7z是一种可以使用多种压缩算法进行数据压缩的档案格式.主要有以下特点: 来源且模块化的组 ...

  10. 6、使用基元类型而不要使用 FCL 类型

    基元类型: int string object uint long ulong 等 ; FCL (Framework Class Library ) System.Int32 等. 一些定义在一些语言 ...