当前位置: 首页 > article >正文

2 月 5 日算法练习- 字符串

人物相关性分析

在这里插入图片描述
思路:枚举+前缀和。枚举字符串中的 Bob 位置利用前缀和来记录,然后枚举 Alice 的位置,通过判断 Bob 在 Alice 前面还是后面来进行不同的前缀和差值计算距离 k 距离中 Bob 的个数求和就是答案,复杂度是 On。注意 Bob 和 Alice 不能是其他字符串的子串要进行判断。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int B[N],b[N],sum1[N],sum2[N];
string s;
int ans;

bool check(int i){
    if(s[i]>='a'&&s[i]<='z')return true;
    if(s[i]>='A'&&s[i]<='Z')return true;
    if(s[i]>='0'&&s[i]<='9')return true;
    return false;
}

int main( ){
    int k;cin>>k;
    cin.get();
    getline(cin, s);
    int n = s.size();
    for(int i=0;i<n;i++){
        if(i+2<n&&s.substr(i,3)=="Bob"){
            if(i+3<n&&check(s[i+3]) || i-1>0&&check(s[i-1]) ){
                B[i] = 1,b[i+2] = 1;
            }
        }
    }
    for(int i=0;i<n;i++)sum1[i] = sum1[i-1]+B[i],sum2[i] = sum2[i-1]+b[i];
    for(int i=0;i<n;i++){
        int A = 0,e = 0;
        if(i+4<n&&s.substr(i,5)=="Alice"){
            if(i+5<n&&check(s[i+5]) || i-1>0&&check(s[i-1]) ){
                A = i,e = i+4;
            }
        }
        ans += sum1[min(e+k,n)] - sum1[e+1-1];
        ans += sum2[A-1] - sum2[max(0,A-1-k-1)];
    }
    cout<<ans<<'\n';
    return 0;
}

子串分值和

在这里插入图片描述

  • 题目改为重复不抵消分数,样例输出是 28,样例说明中 aba 为 2,abab 为 2,ababc 为 3
    思路:通过枚举所有子串复杂度 n^3只能过 50% 的样例。通过找到规律,枚举字符计算贡献,复杂度 On。规律,用到一点贪心的思路,从左到右枚举字符,每个字符的贡献 = 左端点[1,i 字符位置]*右端点[i 字符位置,i 字符下个位置-1] = i字符当前位置 * (i 字符下个位置-i 字符当前位置-1)。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
char s[N];
int suf[N],last[30];
long long ans;
int main( ){
    scanf("%s",s+1);
    int n = strlen(s+1);
    for(int i=0;i<=25;i++)last[i] = n+1;
    for(int i=n;i>=1;i--){
        suf[i] = last[s[i] - 'a'];
        last[s[i] - 'a'] = i;
    }
    for(int i=1;i<=n;i++){
        ans += 1ll * i * (suf[i] - i);
    }
    cout<<ans<<'\n';
    return 0;
}

字串排序

问题描述
小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。在冒泡排序中,每次只能交换相邻的两个元素。小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。例如,对于字符串 lan 排序,只需要 1次交换。对于字符串 qiao 排序V,总共需要 4 次交换。小蓝的幸运数字是 V,他想找到一个只包含小写英文字母的字符串,对这个串中的字符进行冒泡排序,正好需要 V 次交换。请帮助小蓝找一个这样的字符串。如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。请注意字符串中可以包含相同的字符。
输入格式
输入一行包含一个整数"V" ,为小蓝的幸运数字。
输出格式
输出一个字符串,为所求的答案。
样例输入
4
样例输出
bbaa
样例输入
100
样例输出
jihgfeeddccbbaa
评测用例规模与约定
对于 30% 的评测用例,1<=V<=20。
对于 50% 的评测用例,1<=V<=100。
对于所有评测用例,1<=V<=10000。

思路:DFS 过 30% 的数据,复杂度是 7^7,gfedcba V=21 = 6 + 5 + 4 + 3 + 2 + 1。

#include<bits/stdc++.h>
using namespace std;
int V;
string ans = "gfedcba";

void dfs(string s){
    int cnt = 0, len = s.size();
    if(len>7)return;
    string t = s;
    for(int i=0;i<len-1;i++){
        for(int j=0;j<len-1-i;j++){
            if(t[j]>t[j+1]){
                swap(t[j],t[j+1]);
                cnt++;
                if(cnt>V)return;
            }
        }
    }
    if(s.size()>ans.size())return;
    if(cnt == V){
        if(s.size()==ans.size()) ans = min(ans,s);
        else ans = s;
        return ;
    }
    for(int i=0;i<=6;i++)dfs(s+char(i+'a'));
}

int main( ){
    cin>>V;
    dfs("");
    cout<<(string)ans<<'\n';
    return 0;
}

思路:满分需要考验思维,找规律,四星


http://www.kler.cn/a/229067.html

相关文章:

  • 将Docker运行中的容器保存为镜像并导出导入
  • Redis 缓存穿透、击穿、雪崩 的区别与解决方案
  • 若依分页插件失效问题
  • 【Idea启动项目报错NegativeArraySizeException】
  • 采用海豚调度器+Doris开发数仓保姆级教程(满满是踩坑干货细节,持续更新)
  • nginx 配置域名前缀访问 react 项目
  • easyexcel解析跨多行的数据
  • Linux 【docker系列1 - docker 安装与使用】
  • 解决hive表新增的字段查询为空null问题
  • 2.5 作业
  • 从 AGP 4.1.2 升级到 7.5.1——动态添加仓库
  • 【Java】小白友好的MyBatis基础XML开发学习笔记
  • 什么是Java中的弱引用(Weak Reference)和软引用(Soft Reference)?
  • 【漏洞复现】大华智慧园区综合管理平台bitmap接口存在任意文件上传漏洞
  • 某赛通电子文档安全管理系统 UploadFileToCatalog SQL注入漏洞复现
  • 问题:塑瓷后的牙冠要比完成的牙冠大() #学习方法#其他
  • Java入门之JavaSe(韩顺平p1-p?)
  • AI应用开发-python实现redis数据存储
  • LeetCode、1137. 第 N 个泰波那契数【简单,动态规划】
  • 十分钟掌握Go语言==运算符与reflect.DeepEqual函数处理interface{}值的比较规则
  • C++泛型编程:类模板(下)
  • 【Iceberg学习一】什么是Iceberg?
  • 飞天使-k8s知识点12-kubernetes散装知识点1-架构有状态资源对象分类
  • PostgreSQL解决序列(自增id)自动增长冲突
  • 电路设计(10)——超温报警电路的proteus仿真
  • Windows10安装VScode + mingw64 + GSL