codeforces 724D(贪心)
题目链接:http://codeforces.com/contest/724/problem/D
题意:给定一个字符串和一个数字m,选取一个一个子序列s,使得对于字符串中任意长度为m的子序列都至少含有s的位置(不是字符),求所有s在sort后字典序最小的那个字符串。
思路:对字符排序后,从最后一个开始贪心,判断删除该字符后是否符和题意,当删除后不符合题意时,贪心到该相同字符对应的第一个位置为止。
比如对于test3来说
排序后为a a a b b b b c c c c
删除到(b,6)时发现不合题意了,该相同字符对应的第一个位置为(b,3),继续贪心到3为止,结果为a a a b(第二个b) b(第四个b)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 1e5 + 5; 4 char a[N]; 5 struct node 6 { 7 char c; 8 int id; 9 node() {} 10 node(char c,int i) : c(c), id(i) {} 11 bool operator < (const node &t) 12 { 13 if(c != t.c) 14 return c < t.c; 15 return id < t.id; 16 } 17 }q[N]; 18 map<int,bool> mp; 19 map<int,bool>::iterator it; 20 int main() 21 { 22 int m; 23 scanf("%d",&m); 24 scanf("%s",a); 25 int len = strlen(a); 26 for(int i = 0; i < len; i++) 27 { 28 q[i].c = a[i]; 29 q[i].id = i; 30 mp[i]++; 31 } 32 mp[-1] = 1,mp[len] = 1; 33 sort(q,q + len); 34 for(int i = len - 1; i >= 0; i--) 35 { 36 it = mp.find(q[i].id); 37 it--; 38 int t1 = (*it).first; 39 it++,it++; 40 int t2 = (*it).first; 41 if(t2 - t1 > m) 42 { 43 int t = lower_bound(q, q + i + 1, node(q[i].c,0)) - q; 44 for(int j = 0; j < t; j++) 45 printf("%c",q[j].c); 46 for(int j = i; j >= t; j--) 47 { 48 it = mp.find(q[j].id); 49 it--; 50 int t3 = (*it).first; 51 it++,it++; 52 int t4 = (*it).first; 53 if(t4 - t3 <= m) 54 { 55 it--; 56 mp.erase(it); 57 continue; 58 } 59 printf("%c",q[j].c); 60 } 61 return 0; 62 } 63 it--; 64 mp.erase(it); 65 } 66 return 0; 67 }