Week8 CSP模拟 T2 HRZ学英语

题目描述

瑞神今年大三了,他在寒假学会了英文的26个字母,所以他很兴奋!于是他让他的朋友TT考考他,TT想到了一个考瑞神的好问题:给定一个字符串,从里面寻找 连续的26个大写字母 并输出!但是转念一想,这样太便宜瑞神了,所以他加大了难度:现在给定一个字符串,字符串中包括26个大写字母和特殊字符’?’,特殊字符’?'可以代表任何一个大写字母。现在TT问你是否存在一个 位置连续的且由26个大写字母组成的子串 ,在这个子串中每个字母出现且仅出现一次,如果存在,请输出从左侧算起的第一个出现的符合要求的子串,并且要求,如果有多组解同时符合位置最靠左,则输出字典序最小的那个解!如果不存在,输出-1!这下HRZ蒙圈了,他刚学会26个字母,这对他来说太难了,所以他来求助你,请你帮他解决这个问题,报酬是可以帮你打守望先锋。说明:字典序 先按照第一个字母,以 A、B、C……Z 的顺序排列;如果第一个字母一样,那么比较第二个、第三个乃至后面的字母。如果比到最后两个单词不一样长(比如,SIGH 和 SIGHT),那么把短者排在前。例如

AB??EFGHIJKLMNOPQRSTUVWXYZ
输出:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABDCEFGHIJKLMNOPQRSTUVWXYZ

例如上面两种填法,都可以构成26个字母,但是我们要求字典序最小,只能取前者。注意,题目要求的是 第一个出现的, 字典序最小的 !

输入格式

输入只有一行,一个符合题目描述的字符串。

输出格式

输出只有一行,如果存在这样的子串,请输出,否则输出-1

样例输入1

ABC??FGHIJK???OPQR?TUVWXY?

样例输出1

ABCDEFGHIJKLMNOPQRSTUVWXYZ

样例输入2

AABCDEFGHIJKLMNOPQRSTUVW??M

样例输出2

1

思路

这道题我是按一种类似滑动窗口的思想,首先往队列中入队字符串的前26个元素,然后记录‘?’出现的次数cw++,和每个字符出现的次数vis[s[i]-65]++,然后再遍历vis数组,记录其中为0的次数cz,当cz==cw是说明此时是符合条件的字符串区段,特判第一次加入队列是否符合条件,如果不行就继续向后遍历,判断队首元素是是问号,则cw–,否则vis[qe.front()-65]–,判断此时vis[qe.front()-65]是否为0,然后cz++;入队时和出队类似,判断新入队元素是否为问号,cw++,或者vis[s[i]-65]++,如此时vis[s[i]-65]为1,则要cz–,每次出入队操作都要判断cw ==cz,然后按照字典序给?替换输出队列中的元素

代码


#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
queue<char>qe;
int t,n,cnt;
int vis[26]={0};bool flag=1;
string sre;
void show()
{
        for(int i=0;i<26;i++)
        {
            if(qe.front()=='?')
            {
                for(int i=0;i<26;i++)
                {
                    if(vis[i]==0)
                    {
                        vis[i]=1; 
                        printf("%c",i+65); 
                        break;
                    }
                }
            }
            else
            {
                cout<<qe.front();
            }
            qe.pop();
        }   
}
void f2()
{
    int cw=0,cz=0;//记录问号数,未到数
    for(int i=0;i<26;i++)
    {
        qe.push(sre[i]);
        if(sre[i]!='?')
        {
            vis[sre[i]-65]++; 
        }
        else cw++;
    }
    for(int i=0;i<26;i++)
    if(vis[i]==0)cz++;
    if(cz==cw)
    {//提前结束
        show();
        return;   
    }
    //初始化结束
    for(int i=26;i<n;i++)
    {
        if(qe.front()!='?')
        {
            vis[qe.front()-65]--;
            if(vis[qe.front()-65]==0)cz++;
        }
        else cw--;
        qe.pop();
        qe.push(sre[i]);
        if(sre[i]!='?')
        {
            vis[sre[i]-65]++;
            if(vis[sre[i]-65]==1)cz--;
        }
        else cw++;
        if(cz==cw)
        {
            show();
            return ;
        }
    }
    if(cz!=cw)
    cout<<"-1"<<endl;
    else show();
}
int main()
{
    memset(vis,0,sizeof(vis));
    cin>>sre;
    n=sre.size();
   // cout<<n<<endl; 
        f2();
    
    //system("pause");
    return 0;
}
发布了20 篇原创文章 · 获赞 3 · 访问量 450

猜你喜欢

转载自blog.csdn.net/qq_44893580/article/details/105392518
今日推荐