csp模拟B HRZ学英语

题意:

给定一个字符串,看是否有一个连续的26个的子串,其中有26个字母,如果有则输出。注意,字符顺序不需要注意,即不需要一定ABCDE…,并且其中有“?”,“?”字符可以代替任何一个字母。在最终输出这样的字符串的时候,注意将问号替换成字母,其中使得替换后的字典序最小。

input:

一个字符串。

output:

如果存在,则输出这样的最小的字典序字符串。没有的话则输出-1。

思路:

因为是找连续的字符串,想到移动窗口。即保持窗口大小26,开始移动。在读取字符的时候,可以通过将字符转成ASCII码当作数组下标,每次移动一个字符的时候,减去最左侧的字符,加上最右侧的字符。并检查标记的数组,如果从A到Z的数组中有数量为2的则不可能组成26个不同的字母。继续向右移动。当找到这样的数组的时候,则停止遍历。并遍历标记的数组,将其中的为0的字母找出来。再最后输出这个字符串的时候,如果遇到“?”则将其转成这些字母输出,得到最小字典序的子串。

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
using namespace std;
int l=0;
int r=0;
char C[1000100];
int num=0;

int a[28];

char w[27];
int cw;

int f(){
	for(int i=2; i<=27;i++){
		if(a[i]>1)	return -1;
	}	
	return 1;
}

void output(){
	cw=0;
	for(int i=2;i<=27;i++){
		if(a[i]==0){
			w[cw]=i+63;
			cw++;
		}
	}
	
	int  j=0;
	for(int i=l;i<=r;i++){
		if(C[i]!='?'){
			cout<<C[i];
		}else{
			cout<<w[j];
			j++;
		}
	}
	cout<<endl;
}


int main(){
	ios::sync_with_stdio(0);
	for(int i=0; i<28;i++){
		a[i]=0;
	}
	char c;
	c=getchar();
	while( num<26 && c!='\n'){
		C[num]=c;
		num++;
		a[c-63]++;
		c=getchar(); 
	}
	if(num<25){
		cout<<-1<<endl;
		return 0;
	}
	l=0;
	r=25;
	int cs=f();
	if(cs==1){
		output();
		return 0;
	} 

	while(c!='\n'){
		C[num]=c;
		a[C[l]-63]--;
		a[c-63]++;
		l++;
		r++;
		num++;
		int cs=f();
		if(cs==1){
			output();	
			return 0;
		}
		c=getchar();
	}
	cout<<-1<<endl;
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值