蓝桥杯 试题 历届真题 子串分值和【第十一届】【省赛】

  • Post author:
  • Post category:其他



原题叙述

一开始觉得挺简单的,结果做的时候才发现有点坑

不知道为什么,网上查这道题答案时,很多题目给出求分值的定义不一样


分析



针对上述分析可得出

若不考虑重复情况

可得出

s[i] = (len – i) * (i + 1)

一开始没考虑重复三次以上的情况,导致出现了错误

开始的错误答案

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100005;
string s;
ll ans;
ll len;
ll now[30];//存储该字母之前最后出现该字母的下标
int main(){
    cin >> s;
    len = s.length();
    memset(now, -1, sizeof now);//初始化
    for (int i = 0;i < len;i++) {
        int c = s[i] - 'a' + 1;
        ll pos = now[c];
        now[c] = i;
        //首次出现
        if (pos == -1) {
            ans += (len - i) * (i + 1);
        }
        else{
            //ans += (i + 1) * (len - i) - (pos + 1) * (len - i) * 2;
            ans += (i - pos * 2 - 1) * (len - i);//化简后
        }
    }
    cout << ans;
    return 0;
}

最后的正确答案

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100005;
string s;
ll ans;
ll len;
ll pre[N];//存储该字母之前最后出现该字母的下标
ll now[30];//存储该字母之前最后出现该字母的下标
int main(){
    cin >> s;
    len = s.length();
    memset(now, -1, sizeof now);//初始化
    memset(pre, -1, sizeof pre);//初始化
    for (int i = 0;i < len;i++) {
        int c = s[i] - 'a' + 1;
        ll pos = now[c];
        now[c] = i;
        pre[i] = pos;
        //首次出现
        if (pos == -1) {
            ans += (len - i) * (i + 1);
        }
        //第一次重复
        else if(pre[pre[i]] == -1){
            //ans += (i + 1) * (len - i) - (pos + 1) * (len - i) * 2;
            //i  - pos * 2 - 1
            ans += (i - pos * 2 - 1) * (len - i);//化简后
        }
        //二次以上的重复情况
        else {
            //ans += (i + 1) * (len - i) - ((pos + 1)) * (len - i) * 2 + (pre[pre[i]] + 1) * (len - i);
            //i  - pos * 2  + pre[pre[i]]
            ans += (i - pos * 2 + pre[pre[i]]) * (len - i);//化简后
        }
    }
    cout << ans;
    return 0;
}



版权声明:本文为FL_MJ原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。