zoukankan      html  css  js  c++  java
  • Codeforces Round #124 (Div. 2) / C. Lexicographically Maximum Subsequence

    C. Lexicographically Maximum Subsequence
    time limit per test
     2 seconds
    memory limit per test
     256 megabytes
    input
     standard input
    output
     standard output

    You've got string s, consisting of only lowercase English letters. Find its lexicographically maximum subsequence.

    We'll call a non-empty string s[p1p2... pk] = sp1sp2... spk(1 ≤ p1 < p2 < ... < pk ≤ |s|) a subsequence of string s = s1s2... s|s|.

    String x = x1x2... x|x| is lexicographically larger than string y = y1y2... y|y|, if either |x| > |y| and x1 = y1, x2 = y2, ... , x|y| = y|y|, or exists such number r (r < |x|, r < |y|), that x1 = y1, x2 = y2, ... , xr = yr and xr + 1 > yr + 1. Characters in lines are compared like their ASCII codes.

    Input

    The single line contains a non-empty string s, consisting only of lowercase English letters. The string's length doesn't exceed 105.

    Output

    Print the lexicographically maximum subsequence of string s.

    Sample test(s)
    input
    ababba
    
    output
    bbba
    
    input
    abbcbccacbbcbaaba
    
    output
    cccccbba
    
    Note

    Let's look at samples and see what the sought subsequences look like (they are marked with uppercase bold letters).

    The first sample: aBaBBA

    The second sample: abbCbCCaCbbCBaaBA

    分析:

    题目大意就是找一个字典序最大的子序列(和序列的其他子序列相比)。

    一开始的想法是先对序列从大到小稳定排序(用的stable_sort)并记录位置,然后从大的开始输出,要求是后面的字符的原来的位置要大于前面取出的字符最后的位置(也就是说这个字符要比比它大的字符在原来序列中的后面出现,所以需要稳定排序,不然相等的字符再处理时会漏掉)。思路没有什么问题,可没想到提交后超时了。。。看来stable_sort很慢呐。。。

    我的超时代码:

     1 #include <iostream>
     2 #include <cmath>
     3 #include <cstring>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 
     8 struct F
     9 {
    10     char s;
    11     int id;
    12 }f[10001];
    13 
    14 bool cmp(const F &a,const F &b)
    15 {
    16     return a.s>b.s;
    17 }
    18 
    19 int main()
    20 {
    21     char s[10001];
    22 
    23     cin>>s;
    24 
    25     int strl=strlen(s);
    26 
    27     for (int i=0;i<strl;i++)
    28     {
    29         f[i].s=s[i];
    30         f[i].id=i;
    31     }
    32     stable_sort(f,f+strl,cmp);
    33 
    34     int max=-1;
    35     for (int i=0;i<strl;i++)
    36             if (f[i].id>max)
    37             {
    38                 max=f[i].id;
    39                 cout<<f[i].s;
    40             }
    41     cout<<endl;
    42     return 0;
    43 }

    到最后也没想到什么办法~哎。。。

    思路:

    比赛后看了Div.2的rank1的代码,发现原来这么简单。。。

    其实这道题朴素的想法就是每次找一个串中最大的字符取出,这些串就是每次取完的最大字符后面的串。比如abbcbccacbbcbaaba刚开始的串就是本身,然后顺序找到最大的是第四个位置上的c,则取出来,然后串变为bcacbbcbaaba;然后又找到最大的是第二个位置上的c,然后串变成acbbcbaaba;然后又取出第二个位置上的c,串变成bbcbaaba,直到串长度为零。

    但这个想法显然会超时,比我上面的想法更超时,因为每次搜串的最大字符时都要把整个字符全扫一遍。重复工作太多,很浪费时间。

    那么换个思路,从前往后不行,就从后往前嘛。最后一个字符肯定要取,然后只要前面判断的字符大于等于已经取出过的字符就拿出来就行。顺序一遍扫完。K.O.

     1 #include<cstdio>
     2 #include<cstring>
     3 char s[111111],t[111111];
     4 int main(){
     5     scanf("%s",s);
     6     int tot,i;
     7     char lst;
     8     lst=0;
     9     tot=-1;
    10     for (i=strlen(s)-1;i>=0;i--){
    11         if (s[i]>=lst){
    12             t[++tot]=s[i];
    13             lst=s[i];
    14         }
    15     }
    16     for (;tot>=0;tot--) putchar(t[tot]);
    17     puts("");
    18     return 0;
    19 }

    哎。。。好简单呐~~~自己还是太弱了。。。

    举杯独醉,饮罢飞雪,茫然又一年岁。 ------AbandonZHANG
  • 相关阅读:
    rip协议
    IP地址的计算以及子网掩码的计算
    jQuery知识点
    JavaScript 语言编程学习路线
    JS中AJAX知识
    .以及JDK1.5ConcurrentHashMap新特性
    Java程序执行顺序
    观察者设计模式
    Servlet中Filter的学习
    JDBC和连接池知识点
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/2598361.html
Copyright © 2011-2022 走看看