本题为2014年蓝桥杯省赛的填空题。
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
把 abcd...s共19个字母组成的序列重复拼接 106次,得到长度为 2014的串。
接下来删除第 1 个字母(即开头的字母 aa),以及第 3 个,第 5 个等所有奇数位置的字母。
得到的新串再进行删除奇数位置字母的动作。如此下去,最后只剩下一个字母,请输出该字母。
运行限制
- 最大运行时间:1s
- 最大运行内存: 128M
题目链接可见蓝桥官网:用户登录https://www.lanqiao.cn/problems/708/learning/
题解:本题不宜直接采用字符串的删除函数erase()法,因为这个删除函数是不能跨越删除一系列指定位置的字符。本题需要整体一次性删除奇数位置的字符,每一次循环都需要如此。如果采用erase()方法,每删除一个字符就会改变字符的下标,从而删除的位置与题意不符。所以可以采用标识数组,对需要删除的字符的下标进行标记,字符串从头到尾枚举,若该位置(之前没有被标记过)是奇数位置需要删除的标记为true,接下来的每次循环都需要在没有被标记过的字符中进行寻找奇数位置,再进行标记,直至最后总的标记个数达到2013(即只剩下一个字符没有被标记)。在遍历整个字符串,查找唯一没有被标记过的字符的下标,输出该字符,就是答案。
答案:q
参考程序代码:
#include <iostream>
#include <string>
using namespace std;
bool v[2020]; //标识数组,标记字符串中的字母是否需要被删除
int main() {
string s;
for(int i=0; i<106; i++) {
for(int j=0; j<19; j++) {
s+='a'+j;
}
}
int n=s.size(); //获取字符串的长度
int t,cnt=0; //cnt表示字符串中的字母被标记的个数
while(cnt<2013) {
for(int i=0;; i++) {
if(!v[i]) {
t=i; //找到第一个没有被标记的字母的下标
break;
}
}
int c=0; //c表示当前没有被标记的字母的个数
while(t<n) {
if(!v[t]) {
c++;
if(c%2) { //奇数位置,需要删除就标记为true
v[t]=true;
cnt++;
}
}
t++; //遍历整个字符串
}
}
for(int i=0; i<n; i++) {
if(!v[i]) {
cout<<s[i]<<endl;
}
}
return 0;
}