题目如下:
基本思路是通过遍历在每一个字符前面插入与它相同的一个字符,并求得消除的字符数。
例如字符串ABC,分别求AABC、ABBC、ABCC消除掉的字符总数,输出其中的最大值。
#include <iostream>
#include<string>
#include<map>
using namespace std;
/*
计算删除总数:遍历字符串
从下标为1开始遍历,每次看一下和前面的字符是否相同若相同则进入循环依次往后遍历
直到出现不同的字符为止
将erasenum+上相同的字符串,iserase设为true
用一个map记录相同字符出现的首次位置和长度
遍历完之后
把这些相同的字符删掉,并在map中删掉对应的pair
当iserase为false时进入下一次
*/
int biggestclear(string s)
{
int biggestnum = 0;
for (int j = 0; j < s.length(); j++)
{
string copy = s;
copy.insert(j,1, s[j]);
//计算删除总数
int erasenum = 0;
while (1)
{
bool iserase = false;
map<int, int> storeerase;
int m = 1;
while( m < copy.length())
{
if (copy[m] == copy[m - 1])
{
iserase = true;
int samelen = 2;
int exp = m + 1;
while (copy[exp] == copy[m] && exp < copy.length())
{
exp++;
samelen++;
}
storeerase[m - 1] = samelen;
erasenum += samelen;
m += samelen - 1;
}
else
m++;
}
while(!storeerase.empty())
{
map<int, int>::iterator iter = storeerase.end();
iter--;
copy.erase(iter->first, iter->second);
storeerase.erase(iter);
}
if (!iserase) break;
}
if (erasenum > biggestnum) biggestnum = erasenum;
}
return biggestnum;
}
int main()
{
int quesnum; cin >> quesnum;
for (int i = 0; i < quesnum; i++)
{
cout << "case #" << i << ":" << endl;
string s;
cin >> s;
cout << biggestclear(s) << endl;
}
return 0;
}
其中有很多的细节需要注意,详细看代码嗷~特别是消除的时候删除子串的操作:
不能边遍历边删除,会导致循环出错,故我使用了一个map存储要删的起始位置和长度,key(起始位置)=value(长度),循环过一次后再统一进行删除,并且要从后往前删,从前往后删会出错(删过一次后坐标会发生变化)
that's all最后成功AC
扫描二维码关注公众号,回复:
16116144 查看本文章