[codeforces724D]Dense Subsequence

[codeforces724D]Dense Subsequence

试题描述

You are given a string s, consisting of lowercase English letters, and the integer m.

One should choose some symbols from the given string so that any contiguous subsegment of length m has at least one selected symbol. Note that here we choose positions of symbols, not the symbols themselves.

Then one uses the chosen symbols to form a new string. All symbols from the chosen position should be used, but we are allowed to rearrange them in any order.

Formally, we choose a subsequence of indices 1 ≤ i_1 < i_2 < ... < i_t ≤ |s|. The selected sequence must meet the following condition: for every j such that 1 ≤ j ≤ |s| - m + 1, there must be at least one selected index that belongs to the segment [j,  j + m - 1], i.e. there should exist a k from 1 to t, such that j ≤ i_k ≤ j + m - 1.

Then we take any permutation p of the selected indices and form a new string si_p1si_p2... si_pt.

Find the lexicographically smallest string, that can be obtained using this procedure.

输入

The first line of the input contains a single integer m (1 ≤ m ≤ 100 000).

The second line contains the string s consisting of lowercase English letters. It is guaranteed that this string is non-empty and its length doesn't exceed 100 000. It is also guaranteed that the number m doesn't exceed the length of the string s.

输出

Print the single line containing the lexicographically smallest string, that can be obtained using the procedure described above.

输入示例

3
bcabcbaccba

输出示例

aaabb

数据规模及约定

见“输入

题解

贪心贪心使劲贪。。。先暴力求一下必须要用到哪些字母,然后除掉最后一个字母,再用个堆和滑动窗口从左往右扫一遍,贪心地取刚才除掉的那个字母。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;

int read() {
    int x = 0, f = 1; char c = getchar();
    while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
    while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
    return x * f;
}

#define maxn 100010
struct Node {
	char ch; int pos;
	Node() {}
	Node(char _, int __): ch(_), pos(__) {}
	bool operator < (const Node& t) const { return ch != t.ch ? ch > t.ch : pos < t.pos; }
	bool operator == (const Node& t) const { return ch == t.ch && pos == t.pos; }
} ;
priority_queue <Node> Q, delQ;
char S[maxn], ans[maxn];
int cnt, n, m;

bool vis[maxn];
void solve() {
	for(char ch = 'a'; ch <= 'z'; ch++) {
		for(int i = 1; i <= n; i++) if(S[i] == ch) vis[i] = 1, ans[++cnt] = ch;
		int lstp = 0; bool ok = 1;
		for(int i = 1; i <= n; i++) {
			if(vis[i]) lstp = i;
			if(i - lstp == m){ ok = 0; break; }
		}
		if(ok) {
			for(int i = 1; i <= n; i++) if(S[i] == ch) vis[i] = 0, cnt--;
			break;
		}
	}
	return ;
}

int main() {
	m = read();
	scanf("%s", S + 1); n = strlen(S + 1);
	
	solve();
	int lstp = 0;
	for(int i = 1; i < m; i++)
		if(vis[i]) lstp = i;
		else Q.push(Node(S[i], i));
	for(int i = m; i <= n; i++) {
		if(!vis[i]) Q.push(Node(S[i], i));
		else lstp = i;
//		printf("get: %d %d\n", i, lstp);
		if(i - lstp == m) {
			Node u = Q.top(); Q.pop();
			while(!delQ.empty() && u == delQ.top()) delQ.pop(), u = Q.top(), Q.pop();
			ans[++cnt] = u.ch; lstp = u.pos;
//			printf("set: %d\n", lstp);
		}
		if(i > m && !vis[i-m]) delQ.push(Node(S[i-m], i - m));
	}
	
	sort(ans + 1, ans + cnt + 1); ans[cnt+1] = 0;
	printf("%s\n", ans + 1);
	
	return 0;
}

 

posted @ 2017-01-22 16:32  xjr01  阅读(309)  评论(0编辑  收藏  举报