链接:https://ac.nowcoder.com/acm/contest/551/D
来源:牛客网
题目描述
CSL 以前不会字符串算法,经过一年的训练,他还是不会……于是他打算向你求助。
给定一个字符串,只含有可打印字符,通过删除若干字符得到新字符串,新字符串必须满足两个条件:
- 原字符串中出现的字符,新字符串也必须包含。
- 新字符串中所有的字符均不相同。
- 新字符串的字典序是满足上面两个条件的最小的字符串。
输入描述:
仅一行,有一个只含有可打印字符的字符串 s。
|s|≤105|s|≤105
输出描述:
在一行输出字典序最小的新字符串。
思路:本来是不会的,但看完那个人写的感觉思路很好,而且string居然可以当作vector使用,,
比如string a;a.back()返回string最后一个字符,a.pop_back()删除最后一个字符,a.push_back(s)将s插入到string的末尾
所以可以按顺序统计字符串每个字符出现次数,然后定义一个新字符串st,再遍历一次源字符串,定义一个vis数组,表示字符是否在st内,具体还是看代码吧。
#include<bits/stdc++.h>
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define ll long long
#define ld long double
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define me(ar) memset(ar,0,sizeof(ar))
#define lowbit(x) (x&(-x))
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define lcm(a,b) ((a)*(b)/(__gcd((a),(b))))
#define mod 1000000007
#define MP make_pair
#define PI pair<int,int>
using namespace std;
const int N = 1e6 + 100;
int n;
int c[200], vis[200];
int main() {
string s, st;
cin >> s;
for(auto k : s)
c[k]++;
for(auto k : s) {
c[k]--;
if(!vis[k]) {
while(!st.empty() && c[st.back()] && k < st.back()) {//若st不为空并且最后一个字符大于当前字符并且最后一个字符在后面还有
vis[st.back()] = 0;
st.pop_back();
}
st.push_back(k);将此字符插入
vis[k] = 1;
}
}
cout << st << endl;
return 0;
}