字符串分值问题,考虑贡献值

题目:

暴力解法(有点双指针的意思),时间复杂度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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值