贪心+树状数组维护一下 Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) D
http://codeforces.com/contest/724/problem/D
题目大意:给你一个串,从串中挑选字符,挑选是有条件的,按照这个条件所挑选出来的字符集合sort一定是最后选择当中最小的。
从pos=0开始挑选,每次挑选pos~pos+m-1这些位置中的字符,然后下一次再从之前挑选字符的位置开始的后面的m个中进行挑选。
思路:先贪心,按照字典序,每次找到该范围区间内最小的字符,因为该字符一定是串中的一部分,所以必然会被挑选的,于是我们先把这个pos的字符放入集合,并且对挑选过的位置做上标记。按照之前的方法可以先得到了一个集合,但是该集合不一定是最小的,例如m=2的时候cbbadca你前面挑选的集合为baca,但是你会发现还有一个b,如果放入的话字典序会更小,所以我们先得到目前集合中最大的字符,令他为ch,再for一遍把比ch小的再给放进来就好了。
说一下树状数组的作用,因为统计到末尾的时候,我不知道是直接结束还是再放入末尾区间内的某个字母,所以我利用树状数组统计了一下前面所有字符出现的次数,然后查询区间比末尾区间最小的字符串大的字符是否存在,如果存在就放入。
//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = + ;
int n, chlen;
char ch[maxn];
int tree[ + ];
vector<char> v;
char s[maxn];
bool vis[maxn]; void update(int x, int val = ){
for (int i = x; i <= ; i += i & -i){
tree[i] += val;
}
} int sum(int x){
int ans = ;
for (int i = x; i > ; i -= i & -i){
ans += tree[i];
}
return ans;
}
///①并不是越长越好 ②最短长度是已经确定了的③所选出来的一定要比最短的那个的字典序要小
///目标,长度短,字典序短
void solve(){
int pos = , slen = strlen(s);
char minich = ch[pos];
for (int i = pos + ; i < n; i++){
if(minich >= ch[i]){minich = ch[i], pos = i;}
}
vis[pos] = true;
v.pb(minich);
while (pos < chlen){
int minipos = pos + ; minich = ch[minipos];
for (int i = minipos + ; i <= min(chlen, pos + n); i++){
if (minich >= ch[i]){minich = ch[i], minipos = i;}
}
if (pos + n > chlen){
int val = sum() - sum(minich);
if (val == ) break;
}
vis[minipos] = true;
v.pb(minich);
update(minich);
pos = minipos;
}
sort(ALL(v));
char maxch = v[v.size() - ];
for (int i = ; i <= chlen; i++){
if (!vis[i] && maxch > ch[i]){
vis[i] = true; v.pb(ch[i]);
}
}
} int main(){
while (scanf("%d", &n) == ){
memset(vis, false, sizeof(vis));
memset(tree, , sizeof(tree));
memset(s, , sizeof(s));
memset(ch, , sizeof(ch));
scanf("%s", ch);
chlen = strlen(ch);
if (n > chlen) {printf("\n"); continue;}
chlen--;
int cnt = ;
for (int i = ; i <= chlen; i += ){
s[cnt++] = ch[i];
}
solve();
sort(ALL(v));
for (int i = ; i < v.size(); i++){
printf("%c", v[i]);
}
printf("\n");
v.clear();
}
return ;
}
贪心+树状数组维护一下 Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) D的更多相关文章
- CF Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)
1. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) B. Batch Sort 暴力枚举,水 1.题意:n*m的数组, ...
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) E. Goods transportation (非官方贪心解法)
题目链接:http://codeforces.com/contest/724/problem/E 题目大意: 有n个城市,每个城市有pi件商品,最多能出售si件商品,对于任意一队城市i,j,其中i&l ...
- 线段树 或者 并查集 Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) C
http://codeforces.com/contest/722/problem/C 题目大意:给你一个串,每次删除串中的一个pos,问剩下的串中,连续的最大和是多少. 思路一:正方向考虑问题,那么 ...
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)【A,B,C,D】
呵呵哒,上分~ CodeForces 724A: 题意: 给你两个星期几,问连续两个月的头一天是否满足: #include <iostream> #include <stdio.h& ...
- 模拟。。。 Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) C
题目大意:给你一个n*m的矩阵,再给你一个小球,从(0,0)以sqrt(2)/s的速度向右上角出发,遇到边框会反弹,遇到角落就直接停止,给你一些点,问小球第一次经过这些点所需要的时间. 思路:模拟一下 ...
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) E. Goods transportation 动态规划
E. Goods transportation 题目连接: http://codeforces.com/contest/724/problem/E Description There are n ci ...
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) D. Dense Subsequence 暴力
D. Dense Subsequence 题目连接: http://codeforces.com/contest/724/problem/D Description You are given a s ...
- 最小割dp Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) E
http://codeforces.com/contest/724/problem/E 题目大意:有n个城市,每个城市有pi件商品,最多能出售si件商品,对于任意一队城市i,j,其中i<j,可以 ...
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)D Dense Subsequence
传送门:D Dense Subsequence 题意:输入一个m,然后输入一个字符串,从字符串中取出一些字符组成一个串,要求满足:在任意长度为m的区间内都至少有一个字符被取到,找出所有可能性中字典序最 ...
随机推荐
- 【转】关于spring集合对象的补充
<span style="font-size:18px;">关于spring集合对象的补充 spring2.0中对集合对象有了改进,新增了一个<util>标 ...
- 【第二篇】Volley的使用之加载图片
Volley加载图片有两种方式: 1,ImageRequest 来对网络图片进行请求,放入请求队列,获取后现在在控件上面. 2,NetworkImageView 最为自定义控件来自动加载网络图片. 3 ...
- servlet 用法
引入servlet的jar包,这个包在tomcat的lib下 新建一个servlet文件继承httpServlet,要实现里面的doGet或者doPost方法 在web.xml文件中配置 在form表 ...
- Java IO 转换流 字节转字符流
Java IO 转换流 字节转字符流 @author ixenos 字节流 输入字节流:---------| InputStream 所有输入字节流的基类. 抽象类.------------| Fil ...
- Java 集合 集合与数组之间的转换
Java 集合 集合与数组之间的转换 @author ixenos 数组转集合 Arrays.asList(T... a) 先给结论:用 Arrays.asList(T... a) 将数组转换成集合 ...
- 使用UGUI实现拖拽功能(拼图小游戏)
实现方式 1.引入UGUI自带的事件系统 UnityEngine.EventSystems 2.为我们的类添加接口 IBeginDragHandler, IDragHandler, IEndDragH ...
- SHELL自动运行脚本
pass.sh ------------------------ #!/bin/bashecho start /usr/bin/expect <<EOFset timeout 10spaw ...
- tomcat源码分析(一)
tomcat的启动从Bootstrap类的main方法开始. public static void main(String args[]) { //单例 if (daemon == null) { d ...
- redis的适应场景
redis应用场景: 1.对数据高并发读写 2.对海量数据的高效存储和访问 3.对数据的高可扩展性和高可用性 做分布式扩展很简单,因为没有固定的表结构 redis介绍: redis是一个key-val ...
- 查找一个数组中最小的前n项
/****************************************************************** find the biggest x number in a s ...