题目描述
瑞神今年大三了,他在寒假学会了英文的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;
}