题目描述:
给定长度为n的串S,仅包含小写字母。定义
公式中,|A|代表字符串A的长度
也就是说如果子串是一个ABA型的字符串,且满足长度限制,则f(l,r)=1,否则等于0。(注意:形如“ababab”也可视为ABA型)
例如当n=2时,原式为f(1,1)+f(1,2)+f(2,2)。
输入
第一行一个字符串S
第二行一个数字k
输出
输出题目描述中式子的值
样例输入
abcabcabc
2
样例输出
8
提示
1<=n<=2000 , S[i]为小写字母
样例解释:
在这个字符串中,有f(1,5),f(1,8),f(1,9),f(2,6),f(2,9),f(3,7),f(4,8),f(5,9)的值为1,其他为0,故和为8。以f(1,5)为例,选择的子串是abcab,令A=“ab”,B=“c”,则|A|>=k且|B|>=1,因此f(1,5)等于1,以此类推。
分析:
OK,重新整理一下,把例子理一遍,其实就是一个变上下线的加和式子:
样例中的A>=2,B>=1意思就是这个字符串就是ABA式的,其中A和B可能代表长度不一的字符串。
代码:
#include <iostream>
#include <string>
using namespace std;
int f(string s, int l, int r, int k)
{
string subs = s.substr(l-1,r-l+1); //从l开始截取r-l+1个
auto len = subs.size();//子串长度
for (int i=k; i<=len/2; i++)//这里s[0~k]就相当于A
{
//让|A|从k开始增加
string s1 = subs.substr(0,i);//子串的前一部分(从0开始截i个)
string s2 = subs.substr(len-i,i);//子串的后一部分(从len-i开始截i个)
if ((s1 == s2) && (i!=len-i))//若前后相等且为ABA格式则返回1
{
//判断最前和最后的部分是否相同
//cout<<subs<<endl;
//printf("\n");
return 1;
}
}
return 0;
}
int main()
{
string s;
int k;
cin >> s;
cin >> k;
auto n = s.size();
int i, j, res = 0;
for (i=1; i<=n; i++)
{
for (j=i; j<=n; j++)
{
res = res + f(s,i,j,k);
}
}
cout << res << endl;
return 0;
}
笔记:
- 定义字符串时注意
int a[100] = {};
定义时数组不能这样初始化;
int a[100] = {0};
这个写法意味着a[0]=0; substr(pos = 0, count);
参数:
pos,所需的子字符串的起始位置。字符串中第一个字符的索引为 0,默认值为0;
count:要截取的子串的长度;
返回值:一个子字符串,从其指定的位置开始。