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)之 ...
随机推荐
- hdu3499---玄学的分层图
枚举固然可以,但是我还是想看看分层图.... 如本题所述 ,从上图到下图就是一个折扣的过程,上部分只有一种办法下去,下部分图没有办法去上面,该模型十分的巧妙啊!!! 下面我来演示一下自己改的样例吧 紫 ...
- 清晰架构(Clean Architecture)的Go微服务: 日志管理
良好的日志记录可以提供丰富的日志数据,便于在调试时发现问题,从而大大提高编码效率. 记录器提供的自动化信息越多越好,日志信息也需要以简洁的方式呈现,便于找到重要的数据. 日志需求: 无需修改业务代码即 ...
- php strcmp函数漏洞
strcmp函数漏洞 适用5.3版本以前的php 函数作用:字符串比较 要求传入字符串.如果传入非字符串呢? 结果函数报错!但是函数返回“0” . 虽然报错了但函数的判断却是“相等” 如何传入非字符 ...
- 「洛谷P1080」「NOIP2012提高组」国王游戏 解题报告
P1080 国王游戏 题目描述 恰逢 \(H\)国国庆,国王邀请\(n\)位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 \( ...
- V3微信支付开发笔录
真是坑爹啊,微信支付到处都是坑,一不小心就栽里面了, 文档也不怎么全,经过一周的奋斗终于把微信支付功能搞定,在此写下自己当时走入的误区和一些需要注意的地方,希望后边开发的朋友们可以少走弯路,少被微信坑 ...
- Snipaste - 可以提高你工作效率的截图软件
使用Snipaste提高您的工作效率 Snipaste是一个简单但功能强大的剪切工具,还允许您将屏幕截图固定在屏幕上.下载并启动应用程序,按F1开始剪切,然后按F3将其粘贴为浮动窗口.而已! 您还可以 ...
- Go中的Package和Module分析
Package 所谓package(包)其实就是代码的一种组织管理方式,代码多了就需要放入文件,文件多了就需要归类放入文件夹,就好比我们在给电脑装软件时会进行归类安装,其实也是有意无意对电脑软件安装的 ...
- spring boot集成spring-boot-starter-mail邮件功能
前情提要 以目前IT系统功能来看,邮件功能是非常重要的一个功能.例如:找回密码.邮箱验证,邮件动态码.忘记密码,邮件营销等,都需要用到邮件功能.结合当下最流行的spring boot微服务,推出了sp ...
- 【转】ArcGIS ADF 实时轨迹问题初步解决方案
Web ADF 实时轨迹是指在Web客户端指定一资源项,并对资源项进行实进跟踪并绘制出轨迹图.实时绘制可采用Ajax实现服务端与客户端无刷新动态绘制,在.net2.0 框架下可轻易实现:通过客户端时钟 ...
- Java集合框架(java.util包)
集合的概念: 是一种工具类,可以存储任意数量.任意类型的对象(所以后面需要用到泛型,以约束集合中元素的类型) 集合的作用: 1.在类的内部对属性进行组织 2.方便快速定位属性位置 3.某些集合接口,提 ...