cspM2-2

题目要求

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

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

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

求解思路
  • 通过尺取的方式从左向右扫描字符串,并判断当前范围内是否满足要求。
  • con数组用来记录当前时刻26个字母出现的次数
  • nofind记录当前时刻范围中不存在的字母个数,初始化为26.
  • wenhao记录当前时刻范围中的❓个数
  • 尺取法左右指针初始化为0,若right- left < 25,则右指针右移,right+1,若超出字符串范围,则寻找结束,不存在满足要求的字符串,否则,判断str[right]是否为?,或是否为字母,若为❓,则wenhao+1,若为字母,则对应con加一,若该字母第一次出现,则nofind-1
  • right- left = 25,则判断nofind = wenhao,若相等,则找到序列,跳出循环,否则,判断str[left]是否为字母,若为❓,则wenhao-1,若为字母,则对应con减一,若该字母只出现一次,则nofind+1,然后左指针右移,left+1
  • 若找到字符串,为了保证最小字典序,将con为0,即没有出现的元素从小到大存入队列中,从左指针开始遍历原始字符串,若当前字符为❓,则弹出队列头元素。若没找到字符串,输出-1.
代码
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int nofind = 26;
int wenhao = 0;
int con[30];
char str[1000005];
int main()
{
	//scanf("%s", &str);
	for (int i = 0; i < 1000005; i++)
	{
		str[i] = '+';
	}
	cin >> str;
	
	for (int i = 0; i < 30; i++)
	{
		con[i] = 0;//没找到
	}
	int left = 0, right = 0;
	if (str[0] != '?')
	{
		con[str[0] - 'A'] = 1;
		nofind--;
	}
	else
	{
		wenhao++;
	}
	bool findout = false;
	while (str[right] != '+' && right<1000005)
	{
		if (right- left < 25 )
		{
			right++;
			if (str[right] == '+')
			{
				break;
			}
			if (str[right] != '?' )
			{
				if (con[str[right] - 'A'] == 0)
				{
					con[str[right] - 'A'] = 1;
					nofind--;
				}
				else
				{
					con[str[right] - 'A']++;
				}
			}
			else
			{
				wenhao++;
			}
		}
		else if (right - left == 25)
		{
			if (nofind == wenhao )
			{
				findout = true;
				break;
			}
			if (str[left] == '?')
			{
				wenhao--;
			}
			else
			{
				con[str[left] - 'A']--;
				if (con[str[left] - 'A'] == 0)
				{
					nofind++;
				}
			}
			left++;
		}
	}
	
	if (findout == true)
	{
		queue<char> que;
		for (int i = 0; i < 26; i++)
		{
			if (con[i] == 0)
			{
				que.push('A' + i);
			}
		}
		for (int i = 0; i < 26; i++)
		{
			if (str[left + i] != '?')
			{
				printf("%c", str[left + i]);
			}
			else
			{
				char temp = que.front();
				que.pop();
				printf("%c", temp);
			}
		}
	}
	else
	{
		cout << -1;
	}
	return 0;
}

你可能感兴趣的:(算法)