Week8 CSP-M2 B - HRZ 学英语 Gym - 270737D
题目描述:

输入输出规模及约定:

思路:
长度不超过10^6,直接暴力O(26*N),即可。
值得注意的一个点是,如果符合要求,如何按字典序输出?
我的方法是,对26个字符,先统计出现次数cnt[i]。
然后从1到26遍历cnt,发现是0的,就放入队列。
从队列取出的时候就能保证是字典序了。因为队列先进先出。
当然用数组倒序输出也可。
总结:
状态转移的时候,没清空队列和cnt数组!!
当时不知道在想什么!!(可能是亲戚们在客厅吃饭的声音太大了...)
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <map>
using namespace std;
const int MAXN=1e6+5;
char s[MAXN];
queue<int> q; //存储缺失的字符,先进先出
int cnt[200];
map<char,int> mp;
int main()
{
for(int i=0;i<26;i++)
mp['A'+i]=i+1; //26个字母对应1-26
mp['?']=30;
scanf("%s",s+1);
int len=strlen(s+1);
int l=1,r=26;
while(r<=len)
{
int i;
//统计子串中的字符
for(i=l;i<=r;i++)
cnt[ mp[s[i]] ]++;
for(i=1;i<=26;i++)
{
if(cnt[i]==0) q.push(i);
if(cnt[i]>1) break;
}
//如果字母是0或1个,则可以
if(i==27) //搜完了整个26,没发现有多个字符的
{
//输出
for(int j=l;j<=r;j++)
{
if(s[j]!='?') cout<<s[j];
else printf("%c",q.front()+'A'-1),q.pop();
}
cout<<endl;
return 0;
}
else
{
l++,r++;
memset(cnt,0,sizeof(cnt));
while(!q.empty()) q.pop();
}
}
cout<<-1<<endl;
return 0;
}

浙公网安备 33010602011771号