Week8 CSP-M2 B

题目描述:

 输入输出规模及约定:

思路:

长度不超过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; 
}

  

原文地址:https://www.cnblogs.com/qingoba/p/12719584.html