[Offer收割]编程练习赛11 1485 hiho字符串

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

如果一个字符串恰好包含2个'h'、1个'i'和1个'o',我们就称这个字符串是hiho字符串。
例如"oihateher"、"hugeinputhugeoutput"都是hiho字符串。
现在给定一个只包含小写字母的字符串S,小Hi想知道S的所有子串中,最短的hiho字符串是哪个。

输入

字符串S
对于80%的数据,S的长度不超过1000  
对于100%的数据,S的长度不超过100000

输出

找到S的所有子串中,最短的hiho字符串是哪个,输出该子串的长度。如果S的子串中没有hiho字符串,输出-1。

样例输入

happyhahaiohell

样例输出

5

很容易看出来是尺取法。 需要注意必须是恰好包含...., 比赛时没看清楚WA了几次。

#include<bits/stdc++.h>

using namespace std;

string str;

int solve(string &str)
{
    unordered_map<char, int> mp;
    int ans = str.size();
    int b = 0, e = 0;
    bool is = false;
    while(true)
    {
        while(e < str.size() && (mp['h'] >= 2 && mp['i'] && mp['o']) == false)
            mp[str[e++]] ++;

        if(e == str.size())
            break;

        while(b < e && mp['h'] >= 2 && mp['i'] && mp['o'])
        {
            mp[str[b++]] --;
            if(mp['h'] == 2 && mp['i'] == 1 && mp['o'] == 1)
            {
                is = true;
                ans = min(ans, e-b);
                break;
            }
        }
    }
    if(mp['h'] > 1 && mp['i'] && mp['o'])
    {
        while(b < e && mp['h'] > 1 && mp['i'] && mp['o'])
        {
            mp[str[b++]] --;
            if(mp['h'] == 2 && mp['i'] == 1 && mp['o'] == 1)
            {
                is = true;
                ans = min(ans, e-b);
                break;
            }
        }
    }
    if(is)
        return ans;
    else
        return -1;
}

int main()
{
    ios::sync_with_stdio(false);
    cin >> str;
    cout << solve(str) << endl;
    return 0;
}

posted @ 2017-03-26 16:51  aiterator  阅读(297)  评论(0编辑  收藏  举报