[CSL 的字符串][栈,模拟]

链接:https://ac.nowcoder.com/acm/contest/551/D
来源:牛客网
题目描述

CSL 以前不会字符串算法,经过一年的训练,他还是不会……于是他打算向你求助。

给定一个字符串,只含有可打印字符,通过删除若干字符得到新字符串,新字符串必须满足两个条件:
  • 原字符串中出现的字符,新字符串也必须包含。
  • 新字符串中所有的字符均不相同。
  • 新字符串的字典序是满足上面两个条件的最小的字符串。
输入描述:
仅一行,有一个只含有可打印字符的字符串 s。
 
|s|1e5
输出描述:
在一行输出字典序最小的新字符串。
示例1
输入
bab

输出
ab
示例2
输入
baca

输出
bac

备注:
ASCII字符集包含 94 个可打印字符(0x21 - 0x7E),不包含空格。
题解:使用栈进行模拟,如果当前字符已经在栈中,则跳过(保证了每个字符只存一次),否则进行如下操作:如果当前字符比栈顶元素小并且栈顶元素在之后的序列中仍有剩余,就弹出栈顶元素,持续这个过程直到栈顶元素比当前元素小或者栈顶元素没有剩余,然后把当前字符放入栈中(保证了所有字符都会存入栈中)
 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstdio>
 6 #include<vector>
 7 #include<queue>
 8 using namespace std;
 9 typedef long long ll;
10 const ll mod= 998244353;
11 char cc[100005],ch[100005];
12 int in[10005];
13 bool vis[10005];
14 int main(){
15     scanf("%s",ch);
16     int len=strlen(ch);
17     for(int i=0;i<len;i++){
18         in[ch[i]]++;
19     }
20     int tot=0;
21     for(int i=0;i<len;i++){
22         in[ch[i]]--;
23         if(!vis[ch[i]]){
24             vis[ch[i]]=1;
25             while(tot&&cc[tot]>ch[i]&&in[cc[tot]]){
26                 vis[cc[tot]]=0;
27                 tot--;
28             }
29             cc[++tot]=ch[i];
30         }
31     }
32     for(int i=1;i<=tot;i++){
33         printf("%c",cc[i]);
34     }
35     printf("\n");
36     return 0;
37 }
View Code

 

posted @ 2019-03-31 20:51  MekakuCityActor  阅读(299)  评论(0编辑  收藏  举报