解题思路
暴力枚举(只有40%的通过率)
package newPro;
import java.util.*;
public class pro11 {
static String str;
public static void main(String []args)
{
Scanner in=new Scanner(System.in);
str=in.next();
int cnt=0,temp;
for(int i=0;i<str.length();i++)//f[m~n]=s[m~n]+f[m~n-1]依次类推
{
temp=1;
for(int j=1;j<str.length()-i;j++)
{
temp+=S(i,i+j);
}
cnt+=temp;
}
System.out.println(cnt);
}
public static int S(int p,int q)//计算s[p~q]的值
{
int num=0;
char ch[];
int i,j;
ch=str.toCharArray();
for( i=p;i<=q;i++)
{
for( j=p;j<=q;j++)
{
if(ch[i]==ch[j]&&i!=j) break;
}
if(j>q) num++;
}
return num;
}
}
看了大佬的代码顿悟
原理:只有在子串中的个数为1时,才对子串有贡献度
因此可以从向左遍历,和向右遍历,找到最近的相同的字母
ababc中的第二个a举例 ,向左遍历直到第一个相同的字符的字母个数为 left=1
向右遍历直到第一个相同的字符的字母个数为 right=2
因此 第二个a有贡献度的字串为
首先从左边有效的第一个字母开始:ba,bab,bac
第二个字母开始:ab,abc
第三个字母开始:bc
共有3+2+1=6 个 即(1+1)*(2+1)=6
计算公式为:num=(left+1)*(right+1)
import java.util.*;
public class Main{
static String str;
public static void main(String []args)
{
Scanner in=new Scanner(System.in);
str=in.next();
int cnt=0,temp;
char ch[];
int left,right;
ch=str.toCharArray();
for(int i=0;i<str.length();i++)
{ left=0;right=0;
for(int j=i-1;j>=0&&ch[j]!=ch[i];j--)
{
left++;
}
for(int k=i+1;k<str.length()&&ch[k]!=ch[i];k++)
{
right++;
}
cnt+=(left+1)*(right+1);
}
System.out.println(cnt);
}
}