HRZ学英语

题意:

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

在这里插入图片描述

思路:

看到题目的第一眼觉得就是尺取法了每次向右移动区间,具体实现就不赘述了,主要记录一下失分原因。
题目规定了字典序:先按照第一个字母,以 A、B、C……Z 的顺序排列;如果第一个字母一样,那么比较第二 个、第三个乃至后面的字母。
然后注意要求!!第一个出现的,字典序最小的!
所以这里其实只要出现满足26个字母的即可,至于字典序的限制是对含有“?”时令字典序在前面的排在替代靠前的"?"。
我这里理解错了,找了整个序列中字典序最小的,而不是第一个。这里长个记性,好好审题,把题意弄明白了!

代码:

#include<cstdio>
#include<string.h>
#include<map> 
using namespace std;

char str[1000000];
char b[27],c[27];
map<char,int> P;
int num=0;

bool toJudge(int i,int j){
	for(char ch='A';ch<='Z';ch++) P[ch]=0;
	P['?']=0;	
	for(int k=i;k<=j;k++){
		P[str[k]]++;
		if(P[str[k]]>1&&str[k]!='?'){
			return false;
		}
	}
	num=0;
	for(char ch='A';ch<='Z';ch++)
		if(P[ch]==0)  {b[num]=ch;num++;}
	if(num==P['?'])  return true;
	else return false;
}

int main(){
	int v=0,flag=0;;
	while(scanf("%c",&str[v])!=EOF){v++;}
	int l=0,r=25;
	int len=strlen(str);
	while(r<=len-1){
		if(toJudge(l,r)){
			int m=0,n=0;
			for(int x=l;x<=r;x++){
				if(str[x]!='?')	c[m]=str[x];
				else {c[m]=b[n]; n++;}
				m++;
			}
			for(int i=0;i<26;i++) 
				printf("%c",c[i]);
			printf("\n");  flag=1; break;	
		}
		l++;r++;
	}
	if(!flag)   printf("-1\n");
	return 0;	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值