题目:
暴力解法(有点双指针的意思),时间复杂度O(n3):
(大概能骗45分)。。。
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
const int N = 10010;
typedef long long ll;
string s;
int idx;
map<char , int> p;
map<char , int>::iterator it;
int main()
{
cin>>s;
for(int i=0,j=0;j<s.size();i++)
{
if(i==s.size())
{
j++;
i=j;
}
if(j==s.size()) break;
for(int a=i,b=j;b<=a;b++)
{
p[s[b]]++;
}
for(it=p.begin();it!=p.end();it++)
{
if(it->second==1)
{
idx++;
}
}
p.clear();
}
cout<<idx;
return 0;
}
从另一个方向看,可以考虑每个字符对结果的贡献值分别是多少;
分别向左右两个方向查找该字符,向左找到该字符的位置记录为left(找不到就为0);向右找到该字符的位置记录为right(找不到就为字符串长度+1);向左找到的位置就是该字符做贡献的开始,向右找到的位置就是该字符做贡献的结束;
不难推理出:每个字符的贡献值为(i-left)*(right-i) i为该字符的位置(从1开始计数);
那样例来说:第一个a向左查找,left记为0,向右查找,right记为3,那么第一个a的贡献值为
(1-0)*(3-1)==2;
类推:
(2-0)*(4-2)==4;
(3-1)*(6-3)==6;
(4-2)*(6-4)==4;
(5-0)*(6-5)==5;
idx==2+4+6+4+5==21;
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
const int N = 100100;
typedef long long ll;
char s[N];
ll idx;
int main()
{
cin>>s+1;
ll len=strlen(s+1);
ll l=0,r=len+1;
for(int i=1;i<=len;i++)
{
char c;
c=s[i];
ll right=len+1,left=0;
//向左查找到与该字符相同的位置并记录
for(int ll=i-1;ll>=0;ll--)
{
if(s[ll]==c)
{
left=ll;
break;
}
}
//向右查找到与该字符相同的位置并记录
for(int rr=i+1;rr<=len;rr++)
{
if(s[rr]==c)
{
right=rr;
break;
}
}
//记录贡献值
idx+=(i-left)*(right-i);
}
cout<<idx;
return 0;
}