题目
Complete the Word CodeForces - 716B
题目大意
本题给出一个全由大写字母构成的字符串,其中可能包含 “?” 字符,表示此处可以替换为任意大写字母。题目要求我们找出第一次出现的连续包含26个字母的子串,且可以替换"?",要用字典序最小来替换。
解题思路
这道题是第二次CSP限时模拟题目,很遗憾我只对了四个点。先说总体思路,我的思路没有什么问题,就是从头开始遍历长度为26的子串,然后先不管问号,看其中是否有重复字母,有的话就继续后移一位寻找;如果没有重复字母,就从剩余的字母中按照字典序依次选取字母填充问号。
然而这道题我错误地使用了substr函数,并且在字符和数字间的转换处出了问题。这些方面易错且难以找出bug,以后要尽量避免使用,使用时也一定要细致理解。
具体代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <climits>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <vector>
#define ll long long
#define MAXN 100005
#define inf 1e9
using namespace std;
string cmp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int main()
{
int flag[26];
int flagg = 0;
string a;
string ss;
cin >> a;
if(a.size() < 26)
{
cout << -1;
return 0;
}
for(int i = 0; i <= a.size()-26; i++)
{
int flags = 0;
memset(flag,0,sizeof(flag));
ss = "";
for(int j = i; j < i + 26; j++) //substr不能用
{
ss += a[j];
if(a[j] == '?')
{
continue;
}
int tmp = int(a[j] - 'A');
if(!flag[tmp])
{
flag[tmp] = 1;
}
else
{
flags = 1;
break;
}
}
if(!flags)
{
flagg = 1;
break;
}
}
if(!flagg)
{
cout << -1;
return 0;
}
for(int i = 0; i < ss.size(); i++)
{
if(ss[i] == '?')
{
for(int j = 0; j < 26; j++)
{
if(!flag[j])
{
flag[j] = 1;
ss[i] = cmp[j];
break;
}
}
}
}
cout << ss;
return 0;
}