zoukankan      html  css  js  c++  java
  • D、CSL 的字符串 【栈+贪心】 (“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛)

    题目传送门:https://ac.nowcoder.com/acm/contest/551#question

    题目描述 

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

    给定一个字符串,只含有可打印字符,通过删除若干字符得到新字符串,新字符串必须满足两个条件:
    • 原字符串中出现的字符,新字符串也必须包含。
    • 新字符串中所有的字符均不相同。
    • 新字符串的字典序是满足上面两个条件的最小的字符串。
     

    输入描述:

    仅一行,有一个只含有可打印字符的字符串 s。
     
    |s|105|s|≤105

    输出描述:

    在一行输出字典序最小的新字符串。
    示例1

    输入

    复制
    bab

    输出

    复制
    ab
    示例2

    输入

    复制
    baca

    输出

    复制
    bac

    备注:

    ASCII字符集包含 94 个可打印字符(0x21 - 0x7E),不包含空格。

    解题思路:

    贪心,用一个栈逆序保存答案,第一次扫一遍字符串,记录每一个字符最后出现的位置(用于判断栈内元素是否为该类字符的最后那个字符)。

    第二次扫一遍字符串,如果比栈顶元素大或者当前空栈,压栈。否则,如果栈顶的元素比当前元素大并且不是该元素最后的元素,即后面还有栈顶这种元素,那么栈顶元素出栈。

    最后逆序输出栈内元素。

    AC code:

     1 #include <bits/stdc++.h>
     2 #define INF 0x3f3f3f3f
     3 #define LL long long
     4 #define inc(i, j, k) for(int i = j; i <= k; i++)
     5 #define rep(i, j, k) for(int i = j; i < k; i++)
     6 #define mem(i, j) memset(i, j, sizeof(i))
     7 #define gcd(i, j) __gcd(i, j)
     8 using namespace std;
     9 
    10 const int MAXN = 2e5+10;
    11 string str;
    12 stack<char>ss;
    13 map<char, int>mmp;
    14 string ans;
    15 map<char, bool>vis;
    16 int main()
    17 {
    18     cin >> str;
    19     int len = str.size();
    20     rep(i, 0, len){
    21         mmp[str[i]]=i;
    22     }
    23 
    24 
    25     rep(i, 0, len){
    26         if(!vis[str[i]]){
    27             if(ss.empty() || str[i] > ss.top()){
    28                 vis[str[i]] = true;
    29                 ss.push(str[i]);
    30                 continue;
    31             }
    32             while(!ss.empty() && ss.top() > str[i] && mmp[ss.top()] > i){
    33                 vis[ss.top()] = false;
    34                 ss.pop();
    35             }
    36             //puts("zjj");
    37             ss.push(str[i]);
    38             vis[str[i]] = true;
    39         }
    40     }
    41     while(!ss.empty()){
    42 //        printf("%c", ss.top());
    43         ans+=ss.top();
    44         ss.pop();
    45     }
    46     for(int i = ans.size()-1; i >= 0; i--)
    47         printf("%c", ans[i]);
    48     puts("");
    49     return 0;
    50 }
    View Code
  • 相关阅读:
    cesium 学习(七) HeadingPitchRoll
    cesium 学习(六) 坐标转换
    cesium 学习(五) 加载场景模型
    Cesium 学习(一)环境搭建
    Cesium 学习(二)所支持的模型数据类型,以及转换
    cesium 学习(四) Hello World
    Cesium 学习(三)各种资源链接
    【Windows编程】系列第十一篇:多文档界面框架
    【Windows编程】系列第十篇:文本插入符
    【Windows编程】系列第八篇:通用对话框
  • 原文地址:https://www.cnblogs.com/ymzjj/p/10665114.html
Copyright © 2011-2022 走看看