【牛客】Tokitsukaze and Average of Substring

原题链接:登录—专业IT笔试面试备考平台_牛客网

目录

1. 题目描述

2. 思路分析

3. 代码实现


1. 题目描述

2. 思路分析

前缀和。

开一个int类型的前缀和数组pre[30][N](pre[i][j]表示某字符转成的数字 i 在一段区间的前缀个数。因为字母表有‘a’~'z'共26个字母,所以数组的一维至少开26,一般会多开一些,这里我开了30)。

读入字符串s,遍历字符串s(因为是前缀和的题目,所以下标要从1开始),我们将字符串s(string默认下标是从0开始的,所以之后是s[i-1])中的字符转成数字('a'转成1,'b’转成2,...'z'转成26)。 之后从1~26遍历 j(其实就是在遍历字符‘a’~'z'共26个字符),如果当前字符和上一个字符相同(即j==tmp),我们就让前缀和+1,即pre[j][i]=pre[j][i-1]+1;否则pre[j][i]=pre[j][i-1]。

因为n最大是5000。O(N^2)的复杂度不会超时,所以我们可以通过跑两重循环(外层循环枚举左端点,内层循环枚举右端点)来枚举左右区间 l,r 。再从1~26遍历k(还是从'a'遍历到‘z’),开一个变量tmp记录此时的pre[k][r]-pre[k][l-1](也就是字符k对应的数字在 l~r区间的个数),再通过tmp*(tmp-1) 算相同字符对数,并累加到cnt。不断更新ans的值,取max(ans,1.0*cnt/(r-l+1))即可。

因为是多组测试数据,所以每次循环结束要将pre[i][j]这个二维数组置空。

3. 代码实现

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N=5010;
int pre[30][N]; 

void solve(){
    int n; cin>>n;
    string s; cin>>s;
    for(int i=1;i<=n;i++){ //前缀和处理出26个字母的前缀和的数量;
        int tmp=s[i-1]-'a'+1; //字符串下标从0开始
        for(int j=1;j<=26;j++){  //判断当前枚举的字母是否和上一个字母相同
            if(j==tmp) pre[j][i]=pre[j][i-1]+1;
            else pre[j][i]=pre[j][i-1];
        }
    }
    
    double ans=0;
    for(int i=1;i<=n;i++){ //枚举每个区间,然后枚举每个字母,计算贡献。
        for(int j=i+1;j<=n;j++){
            int l=i,r=j;
            int cnt=0;
            for(int k=1;k<=26;k++){
                int tmp=pre[k][r]-pre[k][l-1];
                cnt+=tmp*(tmp-1)/2;
            }
            ans=max(ans,1.0*cnt/(r-l+1));
        }
    }
    cout<<fixed<<setprecision(6)<<ans<<endl;
    
    for(int i=1;i<=26;i++) //多组测试数据,所以每次循环结束将二维数组置空
        for(int j=1;j<=n;j++)
            pre[i][j]=0;
}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T; cin>>T;
    while(T--){
        solve();
    } 
    return 0;
}

  • 23
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值