タイトルの説明
今年はジュニアのルイシェンさんで、冬休みに26文字の英文を習ったので大興奮!それで彼は彼の友人TTに彼をテストするように頼みました、TTはカオリ神の良い質問を考えました:文字列を与えられて、それから26の連続した大文字を見つけて出力します!しかし、これについて考えると、これは安すぎるレイセオンなので、彼は難易度を上げました:文字列を指定すると、文字列には26の大文字と特殊文字が含まれます。'任意の大文字を表すことができます。次に、TTは、26個の大文字で構成される部分文字列が連続する位置にあるかどうかを尋ねます。この部分文字列では、各文字が表示されて1回だけ表示されます。存在する場合は、左から最初に出現する文字を出力してください。要件を満たし、同時に左端の位置を満たすソリューションのセットが複数ある場合、辞書式順序が最小のソリューションが出力されることを要求する部分文字列。存在しない場合は、-1を出力します。これでHRZは円で囲まれました。彼は26文字を学習したばかりですが、難しすぎるので助けを求めてきます。この問題の解決を手伝ってください。支払いはオーバーウォッチのプレイに役立ちます。注:辞書式順序は、最初の文字に従って最初にA、B、C ... Zの順に配置されます。最初の文字が同じ場合は、2番目、3番目、さらにそれ以降の文字を比較します。最後の2つの単語と同じでない場合(たとえば、SIGHとSIGHT)、短い方を最初に置きます。たとえば
AB??EFGHIJKLMNOPQRSTUVWXYZ
输出:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABDCEFGHIJKLMNOPQRSTUVWXYZ
たとえば、上記の2つの塗りつぶし方法で26文字を構成できますが、必要な辞書式順序は最小で、前者のみです。タイトルには、辞書式順序が最小の最初の出現が必要です。
入力フォーマット
タイトルの説明と一致する文字列を1行だけ入力します。
出力フォーマット
出力は1行のみです。そのような部分文字列がある場合は出力してください。それ以外の場合は-1を出力してください
入力例1
ABC ?? FGHIJK ??? OPQR?TUVWXY?
出力例1
ABCDEFGHIJKLMNOPQRSTUVWXYZ
入力例2
AABCDEFGHIJKLMNOPQRSTUVW ?? M
出力例2
1
アイデア
この質問では、スライディングウィンドウのようなアイデアに従って、最初に文字列の最初の26要素をキューに入れ、次に '?'発生回数cw ++、および各文字vis [s [i] -65] ++の発生回数、次にvis配列を走査し、czの回数を記録します。cz== cwは、czが一貫していることを意味します条件付き文字列セクションでは、条件を満たすためにキューに参加するのが初めてかどうかが特別に判断されます。それが機能しない場合は、引き続き後方にトラバースして、チームの最初の要素が疑問符であるかどうかを判断し、次にcw–、それ以外の場合は[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;
}