51nod 1255 贪心/构造

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1255

1255 字典序最小的子序列

题目来源: 天津大学OJ

基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题

收藏

关注

给出一个由a-z组成的字符串S,求他的一个子序列,满足如下条件:

1、包含字符串中所有出现过的字符各1个。

2、是所有满足条件1的串中,字典序最小的。

例如:babbdcc,出现过的字符为:abcd,而包含abcd的所有子序列中,字典序最小的为abdc。

Input

输入1行字符串S,所有字符均为小写,字符串的长度为L。(1 <= L <= 100000)。

Output

输出包含S中所有出现过的字符,每个字符各1个,并且字典序最小的S的子序列。

Input示例

babbdcc

Output示例

abdc

一开始只考虑了待替换字符后面相邻的那一个字符没想到还有可能出现后面数个在后面都可以被更换使得字典序更小的情况,改了以后还是WA竟然是因为前缀和数组zz的写错了cao。。。假设字符x已经出现过了,现在考虑将x删掉查到后面会不会使得结果更优,那么x后面肯定要出现一个小于x的字符且这二者间的字符再后面都要能替换,否则的话并不能使答案优化。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 char s[100005];
 4 deque<char>q;
 5 bool vis[26];
 6 int num[26];
 7 int main()
 8 {
 9     scanf("%s",s+1);
10     int len=strlen(s+1),n,m,i,j,k;
11     for(i=1;i<=len;++i) num[s[i]-‘a‘]++;
12     for(i=1;i<=len;++i)
13     {
14         if(!vis[s[i]-‘a‘]){
15             vis[s[i]-‘a‘]=1;
16             q.push_back(s[i]);
17         }
18         else{
19             for(j=0;j<q.size();++j)
20             {
21                 if(q[j]==s[i]){int j1=-1;
22                 {
23                             for(k=j+1;k<q.size();++k){
24                                 if(q[k]<q[j]){j1=k;break;}
25                             }
26                     if(j1!=-1){
27                         bool ok=1;
28                         for(k=j+1;k<j1;++k)
29                         {
30                             if(num[q[k]-‘a‘]<=0){ok=0;break;}
31                         }
32                         if(ok){
33                             q.erase(q.begin()+j);
34                             q.push_back(s[i]);
35                         }
36                     }
37                     }
38                     break;
39                 }
40             }
41         }
42         num[s[i]-‘a‘]--;
43     }
44     for(int i=0;i<q.size();++i)cout<<q[i];puts("");
45     return 0;
46 }
时间: 2024-09-29 15:59:26

51nod 1255 贪心/构造的相关文章

贪心+构造 Codeforces Round #277 (Div. 2) C. Palindrome Transformation

题目传送门 1 /* 2 贪心+构造:因为是对称的,可以全都左一半考虑,过程很简单,但是能想到就很难了 3 */ 4 /************************************************ 5 Author :Running_Time 6 Created Time :2015-8-3 9:14:02 7 File Name :B.cpp 8 *************************************************/ 9 10 #include

UVA 10821 - Constructing BST(贪心构造)

UVA 10821 - Constructing BST 题目链接 题意:有1 - n的数字,要构造一棵高度不超过h的BST,并且要字典序最小的,输出序列 思路:贪心构造,既然字典序最小,那么每个子树的根都要尽量小,那么也就是右子树尽量填满,按照这个策略去dfs构造即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n, h; void dfs

CF 680D 贪心+构造.

题意:若当前体积为X,则每次选一个最接近X的三次方数(p^3<=X)填入. 确定不超过m的X,使得操作次数最多?若有最大操作次数有多种方案,输出X最大的那一种. m<=1e15. x确定ans也就确定 m很大 直接确定x是不可能的.令最大的a满足,a^3<=m. 则第一个塞的长度最大为a,最多剩下m-a^3如果塞边长a-1的 则体积最大剩下a^3-1-(a-1)^3 保证一开始的体积<a^3.塞a-2的 则最大剩下 (a-1)^3-1-(a-2)^3 此时同样塞了一个,第二个可以选

UVaLive 6588 &amp;&amp; Gym 100299I (贪心+构造)

题意:给定一个序列,让你经过不超过9的6次方次操作,变成一个有序的,操作只有在一个连续区间,交换前一半和后一半. 析:这是一个构造题,我们可以对第 i 个位置找 i 在哪,假设 i  在pos 位置,那么如果 (pos-i)*2+i-1 <= n,那么可以操作一次换过来, 如果不行再换一种,如果他们之间元素是偶数,那么交换 i - pos,如果是奇数,交换 i - pos+1,然后再经过一次就可以换到指定位置. 代码如下: #pragma comment(linker, "/STACK:1

sgu279:Bipermutations(贪心构造)

题目大意: i?j意味着在序列中i的位置在j的前面. 构造一个长度为2n的序列,由1,1′,2,2′...,n,n′构成. 满足如下条件: 1.对于任意i满足i′?i: 2.对于任意i≠j,满足i?j?i′?j′: 3.定义bi,j={j′,j<ij,j>i,ai=∑[i?bi,j],给出序列a,构造出满足a的序列. 分析: 很显然我们要倒着填. 从2n位开始,每次找最小的i使得ai=0填在这一位,更新后面的a,如果找不到,那就找位置最大的没有填过i′的i填在这一位,更新后面的a,否则无解.

51nod 1672 贪心/队列

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1672 1672 区间交 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 小A有一个含有n个非负整数的数列与m个区间,每个区间可以表示为li,ri. 它想选择其中k个区间, 使得这些区间的交的那些位置所对应的数的和最大.(是指k个区间共同的交,即每个区间都包含这一段,具体可以参照样例) 在样例中,5个位置对应的值分别为1,2

51nod 1163 贪心

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1163 1163 最高的奖励 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励.在结束时间之前完成该任务,就可以获得对应的奖励.完成每一个任务所需的时间都是1个单位时间.有时候完成所有任务是不可能的,因为时间上可能会有冲突,这需要你来取舍.求能够获得的最高奖励. Inp

51nod 1255 字典序最小的子序列

1255 字典序最小的子序列 题目来源: 天津大学OJ 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 给出一个由a-z组成的字符串S,求他的一个子序列,满足如下条件: 1.包含字符串中所有出现过的字符各1个. 2.是所有满足条件1的串中,字典序最小的. 例如:babbdcc,出现过的字符为:abcd,而包含abcd的所有子序列中,字典序最小的为abdc. Input 输入1行字符串S,所有字符均为小写,字符串的长度为L.(1 <= L <=

51Nod - 1255

也是第十一届校赛的C题,不过他把1e5改成了1e7. 一开始就想到用贪心做.思路是这样的:开一个字符数组ans保存答案.然后从头到尾遍历题目给出的字符串S,如果ans数组中还没有这个字母,那么就把字母加到ans尾部.如果已经有这个字母了,那么就看ans中这个字母a后面的一个字母b,如果a>b,那么就把a去掉,a后面的字母依次向前一位,然后在ans的尾部加入与a一样的那个字母.后来发现,这个思路是错误的,如果是类似 "egaeg" 这样的字符串,那么这种思路明显无法找到答案. 后来