C - 字典序最小的子序列 51nod1255



C - 字典序最小的子序列

Time Limit: 4000/2000 MS (Java/Others)      Memory Limit: 1280000/640000 KB (Java/Others)

Submit Status

Problem Description

给出一个由a-z组成的字符串S,求他的一个子序列,满足如下条件:
1、包含字符串中所有出现过的字符各1个。
2、是所有满足条件1的串中,字典序最小的。
例如:babbdcc,出现过的字符为:abcd,而包含abcd的所有子序列中,字典序最小的为abdc。

Input

单样例输入。

每个输入1行字符串S,所有字符均为小写,字符串的长度为L。(1 ≤ L ≤ 107)。

所有样例中只有一个样例 L > 105

Output

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

Sample Input

babbdcc

Sample Output

abdc

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int N=1e7+10;
 5 const int INF=0x3f3f3f3f;
 6 int cas=1,T;
 7 char s[N],ans[N];
 8 int a[N],n;
 9 vector<int>q[26];
10 int main()
11 {
12 //  freopen("1.in","w",stdout);
13 //  freopen("21.in","r",stdin);
14 //  freopen("21.out","w",stdout);
15 //  scanf("%d",&T);
16     while(scanf("%s",s)==1)
17     {
18         int n=0;
19         for(;s[n];n++) q[s[n]-‘a‘].push_back(n);
20         a[n]=0;
21         for(int i=n-1;i>=0;i--)
22         {
23             int id=s[i]-‘a‘;
24             a[i]=a[i+1]|(1<<id);
25         }
26         int d=0,an=0,id=0;
27         while(d!=a[0])
28         {
29             for(int i=0;i<26;i++) if((d&(1<<i))==0 && q[i].size())
30             {
31                 auto it=lower_bound(q[i].begin(),q[i].end(),id);
32                 if(it!=q[i].end())
33                 {
34                     if((d|a[*it])==a[0])
35                     {
36                         ans[an++]=i+‘a‘;
37                         d|=1<<i;
38                         id=*it;
39                         break;
40                     }
41                 }
42             }
43         }
44         ans[an]=0;
45         puts(ans);
46     }
47 //  printf("time=%.3lf\n",(double)clock()/CLOCKS_PER_SEC);
48     return 0;
49 }

solve.cpp

题解:

用一个int的bit表示每个字母是否存在,设字母集合为U,从后往前扫一遍算出存在后缀和,即a[i]表示这个数后面有哪些字母
再从前往后扫一遍,记录已有字母的集合U1,对于位置i,每次取能与U1,a[i]并起来能得到全集U 的最小的字母,最后字母集合U1为所求结果

时间: 2024-08-05 07:09:17

C - 字典序最小的子序列 51nod1255的相关文章

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 <=

51Nod1255 字典序最小的子序列

Problem 给出一个由a-z组成的字符串S,求他的一个子序列,满足如下条件: 1.包含字符串中所有出现过的字符各1个. 2.是所有满足条件1的串中,字典序最小的. 例如:babbdcc,出现过的字符为:abcd,而包含abcd的所有子序列中,字典序最小的为abdc. Solution 一个栈,当前没有在栈内,栈顶不是最后一个,且当前更小,就出1个入1个. Code #include<iostream> #include<stdio.h> #include<algorith

3532: [Sdoi2014]Lis 最小字典序最小割

3532: [Sdoi2014]Lis Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 865  Solved: 311[Submit][Status][Discuss] Description 给定序列A,序列中的每一项Ai有删除代价Bi和附加属性Ci.请删除若干项,使得4的最长上升子序列长度减少至少1,且付出的代价之和最小,并输出方案.如果有多种方案,请输出将删去项的附加属性排序之后,字典序最小的一种. 这题难点在如何求一组最小字典序最小的最小

最大子序列和,最小子序列和,最小正子序列和,最大子序列乘积

来自:<数据结构与算法分析——C语言描述>练习2.12 一. 最大子序列和 1.穷举法,O(N3) 1 int maxSequenceSum1(const int A[], int N) 2 { 3 int i, j, k, maxSum, thisSum; 4 5 maxSum = 0; 6 for (i = 0; i < N; i++) 7 { 8 for (j = i; j < N; j++) 9 { 10 thisSum = 0; 11 for (k = i; k <

ZOJ 3204 Connect them(最小生成树之Krusal 输出字典序最小的)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3367 You have n computers numbered from 1 to n and you want to connect them to make a small local area network (LAN). All connections are two-way (that is connecting computers i and j is

贪心:字典序最小问题

*/--> pre.src {background-color: Black; color: White;} pre.src {background-color: Black; color: White;} 贪心:字典序最小问题 给定长度为 n 的字符串 s,要构造一个长度为 n 的字符串 t.起初,t 是一个空串,随后反复进行下列操作 1. 从 s 的头部删除一个字符,加到 t 的尾部 2. 从 s 的尾部删除一个字符,加到 t 的尾部 求 t 是字典序尽可能小的字符串 示例: n = 6 s

poj 1815 Friendship 字典序最小+最小割

题目链接:http://poj.org/problem?id=1815 In modern society, each person has his own friends. Since all the people are very busy, they communicate with each other only by phone. You can assume that people A can keep in touch with people B, only if 1. A kno

hdu1385 Minimum Transport Cost 字典序最小的最短路径 Floyd

求最短路的算法最有名的是Dijkstra.所以一般拿到题目第一反应就是使用Dijkstra算法.但是此题要求的好几对起点和终点的最短路径.所以用Floyd是最好的选择.因为其他三种最短路的算法都是单源的. 输出字典序最小的路径则需要修改模版. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N =1

[poj2337]求字典序最小欧拉回路

注意:找出一条欧拉回路,与判定这个图能不能一笔联通...是不同的概念 c++奇怪的编译规则...生不如死啊... string怎么用啊...cincout来救? 可以直接.length()我也是长见识了... CE怎么办啊...g++来救? #include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #define N 2020