Problem F. Wiki with String
Input file: standard input Time limit: 1 second
Output file: standard output Memory limit: 256 megabytes
现在有一个字符串s, s中只包含数字字符0-9,现在需要输出一个子字符串k满足以下条件:
条件1: k包含0-9中所有的数字字符;
条件2:在所有符合要求的子字符串中, k的长度最小;
条件3:如果存在多个满足条件1和条件2的子字符串,请输出字典序最小的那个子字符串。
Input
输入一个字符串s,且s的长度不大于106
Output
输出符合要求的子字符串k;如果不存在符合要求的子字符串,请输出-1
Samples
standard input | standard output |
00123489765 | 0123489765 |
1234567890123456789 | 0123456789 |
123456789123 | -1 |
思路:采用双指针和贪心的思想,利用set判断当前的子字符串是否符合条件
第一个指针从前到后扫描一遍,第二个指针贪心的往前移动
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <unordered_set> 5 6 7 using namespace std ; 8 9 unordered_set<char> us ; 10 string s ; 11 int cnt[20] ; 12 13 int main(){ 14 15 cin >> s ; 16 17 int la = s.size(),l=0,flag = 0x3f3f3f3f ; 18 int idx = 0 ; 19 string tmp,ans ; 20 for(int i=0;i<la;i++){ 21 us.insert(s[i]) ; 22 cnt[s[i]-'0'] ++ ; 23 while(cnt[s[l]-'0']>1){//如果当前的子字符串内存在重复字符,贪心的让l++,因为新子字符串的长度一定比原子字符串的长度来的短 24 cnt[s[l]-'0'] -- ; 25 l++ ; 26 } 27 if(us.size() == 10){ 28 if(i-l+1<flag){ 29 flag = i-l+1 ; 30 ans = s.substr(l,i-l+1) ; 31 }else if(flag == i-l+1){ 32 tmp = s.substr(l,i-l+1) ; 33 if(tmp<ans){ 34 ans = tmp ; 35 } 36 } 37 idx ++ ; 38 } 39 } 40 if(idx){ 41 cout << ans << endl ; 42 }else{ 43 cout << -1 << endl ; 44 } 45 46 return 0 ; 47 48 }
...