zoukankan      html  css  js  c++  java
  • [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
    ", 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
    ", 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
    ", ans + 1);
    	
    	return 0;
    }
    
  • 相关阅读:
    寒假记录六
    寒假记录5
    寒假记录4
    寒假记录3
    寒假记录2
    寒假记录1
    hive数据库课堂测试
    第一周
    个人总结
    课程总结
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6340714.html
Copyright © 2011-2022 走看看