子串分值(贡献度法)

我一开始用了暴力求解,时间复杂度为n^2,只通过了5个用例

子串分值(贡献度法)_第1张图片
#include 
#include
using namespace std;
int f(string s) {
    int num = 0;
    int jug[26] = { 0 };
    int i;
    for (i = 0; i < s.size(); i++) {
        if (s[i] >= 'a' && s[i] <= 'z') {
            jug[s[i] - 'a']++;
        }
    }
    for (i = 0; i < 26; i++) {
        if (jug[i] == 1) {
            num++;
        }
    }
    return num;
}
int main()
{
    string s;
    cin >> s;
    int all = s.size();
    int k = all;
    int j,i;
    long long cnt = all;
    for (i = 2; i <= k; i++) {
        for (j = 0; j < s.size() - i + 1; j++) {
            cnt += f(s.substr(j, i));
        }
    }
    cout << cnt;
    // 请在此输入您的代码
    return 0;
}

法二:贡献度法,时间复杂度为n

然后这边数据可能比较大,要用long long数据类型。

一个字符(位置为i)的影响范围由其往左边遍历遇到的第一个相同字符(位置为left)和其往右边遍历遇到的第一个相同字符(位置为right)所决定。其贡献值为(i - left)*(right - i);

acbe,acb,cbe,cb,b,be共有6个(这些子串的f值都因为b增加了1,而bacb这个子串不会因为3号b增加f值),这些子串的起点可以为1、2、3,终点可以为3、4,即(3-0)*(5-3) = 6.

#include 
#include
using namespace std;
int main()
{
  string s;
  cin>>s;
  long long num=0;
  long long len=s.length();
  long long i;
  long long j;
  long long left,right;
  for(i=0;i=0;left--){
      if(s[left]==k){
        break;
      }
    }
    for(right=i+1;right

你可能感兴趣的:(蓝桥杯,c++,算法,数据结构)