codeforces 797c minimal string

2017-08-01 21:49:34

writer:pprp

集训第一天

题意如下:

• Codeforces 797C Minimal string
• 给定长度为n的小写字母字符串s,及空串t, u,两种操作
• 1. 将s的第一个字符加到t的末尾
• 2. 将t的最后一个字符加到u的末尾
• 求字典序最小的字符串u (长度必须为n,即s, t最后为空串)
• 1 ≤ n ≤ 1e5

算法分析:将t看做是栈stack,将u看做是队列queue,s作为向量vector

    优先考虑将最小的比如说a,按照a的位置,将这个字符串分成几部分,如:dx|a|cdb|a|bsd

            s: bsd

     t:dxcdb

       u:aa

做成上述之后分别比较s和t中弹出的大小,先将小的放到前边,大的放到后边,最后得到最小字典序的字串;


代码如下:(在cf上有错误,卡在了第11条,也不知道怎么回事,只有一个字符不相等)

     

#include <iostream>
#include <vector>
#include <stack>
#include <queue>

using namespace std;

stack <int> sta;
vector <int> vec(26,0);
vector <int> vv;
queue <char> qu;

int main()
{
    string str;

    cin >> str;

    for(int i = 0; i < (int)str.length() ; i++)
    {
        vv.push_back(str[i] - 'a');
    }

    for(int i = 0 ; i < (int)str.length() ; i++)
    {
        vec[str[i]-'a']++;
    }

    int j;
    for(j = 0 ; j < (int)vec.size() ; j++)
        if(vec[j])
            break;

    int cnt = vec[j];

    while(1)
    {
        if(vv.front() != j)
        {
            sta.push(vv.front());
            vv.erase(vv.begin());
        }
        else
        {
            qu.push(vv.front() + 'a');
            vv.erase(vv.begin());
            cnt--;
        }
        if(cnt == 0)
            break;
    }

    while(!sta.empty() && !vv.empty())
    {
        if(vv.front() <= sta.top())
        {
            qu.push(vv.front() + 'a');
            vv.erase(vv.begin());
        }
        else
        {
            qu.push(sta.top() + 'a');
            sta.pop();
        }
    }
    if(!vv.empty())
    {
        while(!vv.empty())
        {
            sta.push(vv.front());
            vv.erase(vv.begin());
        }
    }
    if(!sta.empty())
    {
        while(!sta.empty())
        {
            qu.push(sta.top() + 'a');
            sta.pop();
        }
    }
    while(!qu.empty())
    {
        cout << qu.front() ;
        qu.pop();
    }

    return 0;
} 

现在回过头来看这个题,明白了其实一开始理解就是错误的,不仅仅在一开始要这样进行,在之后比如说:

b a c d a c s b s a b d c s b c c

这一串,不仅仅对所有的a都是这样处理,

先处理成:

S: b d c s b c c

T:b c d c s b s

U:a a a 

以上是之前理解的,在之后的操作出现问题,不应该将S和T进行大小比较,而应该对S串做进一步处理:对S中较小值b处理

S:c c

T:b c d c s b s d c s 

U: a a a b b 

继续对S处理

S:

T:b c d c s b s d c s 

U: a a a b b c c

将T全部出栈

S:

T:

U: a a a b b c c b c d c s b s d c s 

以上才是正确的方法

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <stack>

using namespace std;

const int maxn = 100005;

int cnt[27];
stack <char> q;
char s[maxn];
string str;

bool Find_min(char c)
{
    int n = c - 'a';
    for(int i = 0 ; i < n ; i++)
    {
        if(cnt[i])
            return true;
    }
    return false;
}
void init()
{
    memset(cnt,0,sizeof(cnt));
    int len = str.size();
    for(int i = 0 ; i < len ; i++)
    {
        cnt[str[i]-'a']++;
    }
}

int main()
{
    while(cin >> str)
    {
        init();
        int l = str.size();

        q.push(str[0]);
        cnt[str[0]-'a']--;

        for(int i = 1 ; i < l ; i++)
        {
            while(!q.empty() && !Find_min(q.top()))
            {
                char tmp = q.top();
                cout << tmp;
                q.pop();
            }
            q.push(str[i]);
            cnt[str[i]-'a']--;
        }
        while(!q.empty())
        {
              cout << q.top();
              q.pop();
        }
    }
    
}

AC代码如下:

原文地址:https://www.cnblogs.com/pprp/p/7270906.html