时间限制: 1Sec 内存限制: 128MB 提交: 289 解决: 57
题目描述
对于一个字符串S,我们定义S 的分值 f(S) 为S中恰好出现一次的字符个数。例如f (”aba”) = 1,f (”abc”) = 3, f (”aaa”) = 0。
现在给定一个字符串S[0…n-1](长度为n),请你计算对于所有S的非空子串S[i…j](0 ≤ i ≤ j < n), f (S[i… j]) 的和是多少。
输入
输入一行包含一个由小写字母组成的字符串S。
输出
输出一个整数表示答案。
样例输入复制
ababc
样例输出复制
21
提示
样例说明:
子串f值:
a 1
ab 2
aba 1
abab 0
ababc 1
b 1
ba 2
bab 1
babc 2
a 1
ab 2
abc 3
b 1
bc 2
c 1
对于20% 的评测用例,1 ≤ n ≤ 10;
对于40% 的评测用例,1 ≤ n ≤ 100;
对于50% 的评测用例,1 ≤ n ≤ 1000;
对于60% 的评测用例,1 ≤ n ≤ 10000;
对于所有评测用例,1 ≤ n ≤ 100000。
法一:暴力求解时间超限 只得了五十分
#include<bits/stdc++.h>
using namespace std;
string s;
int a[100];
long long cot=0;
int main()
{
cin>>s;
long long l=s.length();
for(int i=0;i<l;i++)
{
for(int j=i;j<l;j++)
{
memset(a,0,sizeof(a));
for(int k=i;k<=j;k++)
{
a[s[k]-97]++;
}
for(int g=0;g<27;g++)
{
if(a[g]==1)
{
cot++;
}
}
}
}
cout<<cot;
return 0;
}
法二:求包含下标为i的字母的不重复子串
左边的子串个数加一乘以 右边的子串个数加一
子串从下标为i开始往左往右开始查找 找到重复的即停止
满分
#include<bits/stdc++.h>
using namespace std;
string s;
int a[100];
long long sum=0;
int main()
{
cin>>s;
long long ll=s.length();
int left=0;
int ringht=0;
for(int i=0;i<ll;i++)
{
int m=(s[i]-97);
long long l=0;
long long r=0;
for(int left=i-1;left>=0;left--)
{
int n=(s[left]-97);
if(m!=n)
{
l++;
}
if(m==n)
{
break;
}
}
for(int right=i+1;right<ll;right++)
{
int n=(s[right]-97);
if(m!=n)
{
r++;
}
if(m==n)
{
break;
}
}
sum+=(r+1)*(l+1);
}
cout<<sum;
}