题目传送门:http://codeforces.com/contest/724/problem/D
题意:给一个字符串和一个数m,让你从中取出一串非连续子串。使原串中每m个元素,至少含一个子串中的元素(位置也要对应),输出符合要求的子串中字典序最小的(子串元素顺序可打乱)
思路:贪心,先找出满足条件的子串最大字母的最小可能,然后将原串中小于最大字母的元素加到子串中,最后删除尽可能多的最大字母。
一起总觉得贪心跟暴力属于比较简单的算法,但是越简单的算法套路也越多,题也越灵活啊
代码如下:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdio.h>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <bitset>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ll long long
#define ull unsigned long long
#define mem(n,v) memset(n,v,sizeof(n))
#define MAX 100005
#define MAXN 10005
#define PI 3.1415926
#define E 2.718281828459
#define opnin freopen("text.in.txt","r",stdin)
#define opnout freopen("text.out.txt","w",stdout)
#define clsin fclose(stdin)
#define clsout fclose(stdout)
#define haha1 cout << "haha1"<< endl
#define haha2 cout << "haha2"<< endl
#define haha3 cout << "haha3"<< endl
const int INF = 0x3f3f3f3f;
const ll INFF = 0x3f3f3f3f3f3f3f3f;
const double pi = 3.141592653589793;
const double inf = 1e18;
const double eps = 1e-8;
const ll mod = 1e18;
const ull mx = 133333331;
/**************************************************************************/
string str;
char ans[MAX];
int main()
{
int cnt = 0;
mem(ans,0);
int m;
string temp;
cin >> m >> temp;
str = '@';
str += temp;
int len = str.size();
int id = 1;
for(int i=2;i<=m;i++){
if(str[i] <= str[id])
id = i;
}
ans[cnt++] = str[id];
int i = id+1;
while(i < len-m+1){
id = i;
for(int j=i+1;j<=i+m-1;j++){
if(str[j] <= str[id])
id = j;
}
ans[cnt++] = str[id];
i = id+1;
}
sort(ans,ans+cnt);
char index = ans[cnt-1];
id = 0;
cnt = 0;
for(int j=1;j<len;j++){
if(str[j] < index){
ans[cnt++] = str[j];
}
}
for(int i=1;i<len;i++){
if(str[i] < index) id = i;
else if(i - id >= m){
int j = i;
while(str[j] != index) j--;
ans[cnt++] = str[j];
id = j;
}
}
sort(ans,ans+cnt);
ans[cnt] = 0;
printf("%s\n",ans);
}