Codeforces Round #617 (Div. 3) String Coloring(E1.E2)
(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)的更多相关文章
- Codeforces Round #378 (Div. 2) D题(data structure)解题报告
题目地址 先简单的总结一下这次CF,前两道题非常的水,可是第一题又是因为自己想的不够周到而被Hack了一次(或许也应该感谢这个hack我的人,使我没有最后在赛后测试中WA).做到C题时看到题目情况非常 ...
- Codeforces Round #367 (Div. 2) A. Beru-taxi (水题)
Beru-taxi 题目链接: http://codeforces.com/contest/706/problem/A Description Vasiliy lives at point (a, b ...
- Codeforces Round #603 (Div. 2) E. Editor(线段树)
链接: https://codeforces.com/contest/1263/problem/E 题意: The development of a text editor is a hard pro ...
- Codeforces Round #515 (Div. 3) 解题报告(A~E)
题目链接:http://codeforces.com/contest/1066 1066 A. Vova and Train 题意:Vova想坐火车从1点到L点,在路上v的整数倍的点上分布着灯笼,而在 ...
- Codeforces Round #222 (Div. 1) Maze —— dfs(连通块)
题目链接:http://codeforces.com/problemset/problem/377/A 题解: 有tot个空格(输入时统计),把其中k个空格变为wall,问怎么变才能使得剩下的空格依然 ...
- Codeforces Round #336 (Div. 2) D. Zuma(区间DP)
题目链接:https://codeforces.com/contest/608/problem/D 题意:给出n个宝石的颜色ci,现在有一个操作,就是子串的颜色是回文串的区间可以通过一次操作消去,问最 ...
- Codeforces Round #316 (Div. 2) C. Replacement(线段树)
C. Replacement time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...
- 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 ...
- Codeforces Round #626 (Div. 2) D. Present(位运算)
题意: 求n个数中两两和的异或. 思路: 逐位考虑,第k位只需考虑0~k-1位,可通过&(2k+1-1)得到一组新数. 将新数排序,当两数和在[2k,2k+1)和[2k+1+2k,2k+2)之 ...
随机推荐
- Spring Boot 整合 slf4j+log4j 实现日志管理
一:首先新建一个jar项目,如下图: 二:添加log4j的依赖,如下pom.xml文件: <project xmlns="http://maven.apache.org/POM/4.0 ...
- mysql主从之Mysql_mysql基本安装
下载安装包: https://dev.mysql.com/downloads/mysql/5.7.html#downloads [root@jenkins-master ~]# cd /usr/loc ...
- Python 进程、线程、协程的介绍与使用
一.必备的理论基础 二.操作系统发展史 三.进程理论 四.线程理论 五.协程 一.必备的理论基础 操作系统理论: 操作系统是一个协调\管理\控制计算机硬件资源与应用软件资源的控制程序 操作系统的两大功 ...
- floj 2264
2.公路建设(highway.c/cpp/pas) 在滨海市一共有n 个城市,编号依次为1到n,它们之间计划修建m条双向道路,其中修建第i条道路的费用为ci. 海霸王作为滨海市公路建设项目的总工程师, ...
- crawler 听课笔记 碎碎念 3 关于python的细枝末节的回顾复习
和廖雪峰大神的教程学了几遍后,还是出现了许多不足,于是就做一些回顾,列出一些python的细节问题,有一些就提一下,如果发现不清楚的话 还请移步https://www.liaoxuefeng.com/ ...
- 20190925Java课堂记录(一)
判断字符串是否回文 设计思想 利用递归,每次返回长度减二的字符串,最终返回结果 源程序代码 import java.util.Scanner; public class palindrome { st ...
- 如何添加.pch文件
1.Create a pch , call name is project+xxx.pch For example: DuoME-PrefixHeader.pch 2.在project——>Bu ...
- 搞定SpringBoot多数据源(3):参数化变更源
目录 1. 引言 2. 参数化变更源说明 2.1 解决思路 2.2 流程说明 3. 实现参数化变更源 3.1 改造动态数据源 3.1.1 动态数据源添加功能 3.1.2 动态数据源配置 3.2 添加数 ...
- 关于Navicat连接oralcle出现Cannot load OCI DLL 87,126,193 ,ORA-28547等错误
navicat连接oracle数据库报ORA-28547: connection to server failed, probable Oracle Net admin error错误的解决方法 na ...
- 【Java面试】java基础篇
总结个人的面试经历以及一些网上的的面试题,以供以后面试与巩固java基础. 1.String.StringBuilder和StringBuffer的区别 String用于存储不可变字符串的类,Stri ...