第十五届蓝桥杯省赛第二场C/C++B组D题【前缀总分】题解(AC)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

暴力解法 O ( 26 n 5 ) O(26n^5) O(26n5)

枚举将第 i i i 个字符串的第 j j j 个字符改为 c c c 的所有方案,时间复杂度 O ( 26 n 2 ) O(26n^2) O(26n2),修改并计算总分, O ( n 3 ) O(n^3) O(n3)

暴力优化 O ( 26 n 3 log ⁡ n ) O(26n^3\log n) O(26n3logn)

我们可以使用字符串哈希来优化判断两个字符串是否相等。

另外,可以用二分来优化求两个字符串的最大前缀。

枚举所有方案的时间复杂度为 O ( 26 n 2 ) O(26n^2) O(26n2),处理修改以及计算总分的复杂度为 O ( n log ⁡ n ) O(n\log n) O(nlogn)

再优化 O ( 26 n 3 ) O(26n^3) O(26n3)

首先,我们依旧使用上述暴力解法中的枚举方式——所有将第 i i i 个字符串的第 j j j 个字符改为 k k k,时间复杂度 O ( 26 n 2 ) O(26n^2) O(26n2)

接下来我们考虑,如果用不大于 O ( n ) O(n) O(n) 的时间去完成计算一个枚举的分数。

将第 i i i 个字符串的第 j j j 个字符改为 k k k 时,所影响答案的只有 P ( s 1 , s i ) , P ( s 2 , s i ) , P ( s 3 , s i ) , … , P ( s n , s i ) P(s_1, s_i), P(s_2, s_i), P(s_3, s_i), \dots, P(s_n, s_i) P(s1,si),P(s2,si),P(s3,si),,P(sn,si)

所以我们可以计算出未修改时的总得分的 t o t tot tot,计算出未修改时第 i i i 个字符串对答案的贡献 g [ i ] g[i] g[i]。设修改之后第 i i i 个字符串对答案的贡献为 r e s res res,那么修改之后的答案即为 t o t − g [ i ] + r e s tot - g[i] + res totg[i]+res

那么接下来,我们要尝试处理计算,将第 i i i 个字符串的第 j j j 个字符改为 k k k 之后,第 i i i 个字符串对答案的贡献。

那么显而易见,我们需要计算修改之后的第 i i i 字符串与剩下 n − 1 n-1 n1 个字符串的最大前缀。

设其中一个字符串为 s u s_u su,计算修改之后的 s i s_i si 与修改之前,只有第 j j j 个字符被改变, j j j 左侧的字符,以及右侧的字符均为改变。

那么我们可以尝试比较修改前的 s i s_i si s u s_u su 0 0 0 开始的最大前缀长度 l e f t left left

  • l e f t < j − 1 left < j - 1 left<j1,那么 s i s_i si s u s_u su 的最大前缀长度即为 l e f t left left
  • l e f t ≥ j − 1 left \geq j - 1 leftj1,那么说明 s i s_i si s u s_u su 的前 j − 1 j - 1 j1 个字符相等,此时我们需要判断修改之后的第 j j j 个字符是否相等:
    • 若第 j j j 个字符相等,则 s i s_i si s u s_u su 的最大前缀即为 l e f t + 1 + left + 1 + left+1+ s i s_i si s j s_j sj 的第 j + 1 j + 1 j+1 个字符开始的最大前缀)。
    • 若第 j j j 个字符不相等,则 s i s_i si s u s_u su 的最大前缀即为 l e f t left left

上述分析中,我们多次需要用到第 i i i 个字符串与第 j j j 个字符串从 k k k 开始的最大前缀。

考虑动态规划: f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k] 表示第 i i i 个字符串与第 j j j 个字符串从 k k k 开始的最大前缀长度。

考虑动态转移:

  • s [ i ] [ k ] = s [ j ] [ k ] s[i][k] = s[j][k] s[i][k]=s[j][k],则 f [ i ] [ j ] [ k ] = f [ i ] [ j ] [ k + 1 ] + 1 f[i][j][k] = f[i][j][k + 1] + 1 f[i][j][k]=f[i][j][k+1]+1
  • s [ i ] [ k ] ≠ s [ j ] [ k ] s[i][k] \neq s[j][k] s[i][k]=s[j][k],则 f [ i ] [ j ] [ k ] = 0 f[i][j][k] = 0 f[i][j][k]=0

由于计算 f [ i ] [ j ] [ k + 1 ] f[i][j][k + 1] f[i][j][k+1] 时,需要用到 f [ i ] [ j ] [ k + 1 ] f[i][j][k + 1] f[i][j][k+1],故预处理 f f f 数组时需要倒序处理。

暴力优化 O ( 26 n 3 log ⁡ n ) O(26n^3\log n) O(26n3logn)

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>using namespace std;const int N = 2e2 + 10, P = 131;typedef unsigned long long ULL;int n;
string str[N];
ULL f[N][N], p[N];
int g[N];
int tot;ULL query(int u, int l, int r)
{return f[u][r] - f[u][l - 1] * p[r - l + 1];
}int calc(int u, bool flag)
{int res = 0;for (int i = 1; i <= n; ++ i )if (i != u){int l = 1, r = min(str[u].size() - 1, str[i].size() - 1);while (l < r){int mid = l + r + 1 >> 1;if (query(i, 1, mid) == query(u, 1, mid))l = mid;elser = mid - 1;}if (query(i, 1, l) == query(u, 1, l))res += l;}if (flag){g[u] = res;tot += res;}return res;
}int modify(int u, int k, int c)
{char t = str[u][k];str[u][k] = 'a' + c;for (int i = 1; i < str[u].size(); ++ i )f[u][i] = f[u][i - 1] * P + str[u][i];int res = tot - g[u] * 2 + calc(u, false) * 2;str[u][k] = t;for (int i = 1; i < str[u].size(); ++ i )f[u][i] = f[u][i - 1] * P + str[u][i];return res / 2;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin >> n;for (int i = 1; i <= n; ++ i ){cin >> str[i];str[i] = ' ' + str[i];}p[0] = 1;for (int i = 1; i < N; ++ i )p[i] = p[i - 1] * P;for (int i = 1; i <= n; ++ i )for (int j = 1; j < str[i].size(); ++ j )f[i][j] = f[i][j - 1] * P + str[i][j];for (int i = 1; i <= n; ++ i )calc(i, true);int res = 0;for (int i = 1; i <= n; ++ i )for (int j = 1; j < str[i].size(); ++ j )for (int k = 0; k < 26; ++ k )res = max(res, modify(i, j, k));cout << res << endl;return 0;
}

再优化 O ( 26 n 3 ) O(26n^3) O(26n3)

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>using namespace std;const int N = 2e2 + 10;int n;
string str[N];
int g[N];
int tot;
int f[N][N][N];     //  [i, j, k] 第i个字符串和 第j个字符串 k个字符起最大连续数量void init()
{for (int i = 1; i <= n; ++ i )for (int j = i + 1; j <= n; ++ j ){int mn = min(str[i].size(), str[j].size());for (int k = mn - 1; k >= 0; -- k )if (str[i][k] == str[j][k])f[i][j][k] = f[j][i][k] = f[i][j][k + 1] + 1;}for (int i = 1; i <= n; ++ i ){for (int j = 1; j <= n; ++ j )g[i] += f[i][j][0];tot += g[i];}tot /= 2;
}int modify(int u, int k, int c)
{int res = 0;for (int i = 1; i <= n; ++ i )if (i != u){int left = min(f[u][i][0], k);res += left;if (left == k && str[i].size() > k && str[i][k] - 'a' == c){res ++;res += f[u][i][k + 1];}}return tot - g[u] + res;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin >> n;for (int i = 1; i <= n; ++ i )cin >> str[i];init();int res = 0;for (int i = 1; i <= n; ++ i )for (int j = 0; j < str[i].size(); ++ j )for (int k = 0; k < 26; ++ k )res = max(res, modify(i, j, k));cout << res << endl;return 0;
}

【在线测评】

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/3542.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Python实现心脏病数据可视化DEA+预测【500010103.1】

一、数据说明 该心脏病数据集是通过组合 5 个已经独立可用但以前未合并的流行心脏病数据集来策划的。在这个数据集中&#xff0c;5 个心脏数据集结合了 11 个共同特征&#xff0c;使其成为迄今为止可用于研究目的的最大心脏病数据集。 该数据集由 1190 个实例和 11 个特征组成…

《第二行代码》第二版学习笔记(6)——内容提供器

文章目录 一 运行时权限2.权限分类3 运行时申请权限 二、内容提供器1、 ContentResolver的基本用法2、现有的内容提供器3、创建自己的内容提供器2.1 创建内容提供器的步骤2.2 跨程序数据共享 内容提供器&#xff08;Content Provider&#xff09;主要用于在不同的应用程序之间实…

Python | Leetcode Python题解之第52题N皇后II

题目&#xff1a; 题解&#xff1a; class Solution:def totalNQueens(self, n: int) -> int:def backtrack(row: int) -> int:if row n:return 1else:count 0for i in range(n):if i in columns or row - i in diagonal1 or row i in diagonal2:continuecolumns.add…

【VsCode】使用VsCode学习VUE+TS必备插件

目录标题 《Auto Close Tag》&#x1f495;《Auto Rename Tag》&#x1f495;《Path Intellisense》《Open in Browser》&#x1f495;《IntelliCode》《Vue-Official》&#x1f495;《Prettier - Code formatter》&#x1f495;《ESLint》&#x1f495; 《Auto Close Tag》&am…

Docker镜像的创建 和 Dockerfile

一. Docker 镜像的创建 创建镜像有三种方法&#xff0c;分别为基于已有镜像创建、基于本地模板创建以及基于 Dockerfile 创建。 1 基于现有镜像创建 &#xff08;1&#xff09;首先启动一个镜像&#xff0c;在容器里做修改docker run -it --name web3 centos:7 /bin/bash …

maven修改默认编码格式为UTF-8

执行mvn -version查看maven版本信息发现&#xff0c;maven使用的编码格式为GBK。 为什么想到要修改编码格式呢&#xff1f;因为idea中我将文件格式统一设置为UTF-8&#xff08;如果不知道如何修改文件编码&#xff0c;可以参考文末&#xff09;&#xff0c;然后使用maven打包时…

docker 和 docker-compose的区别

Docker 和 Docker Compose 是两个相关但具有不同功能的工具&#xff0c;它们在容器化应用的生命周期管理中扮演不同的角色&#xff1a; Docker&#xff1a; Docker 是一个开源的应用容器引擎&#xff0c;它允许开发者打包应用及其依赖包到一个可移植的容器中&#xff0c;这样…

ESP32与SD卡交互实现:文件读写实战与初始化详解及引脚定义

本代码实现ESP32与SD卡的交互&#xff0c;包括定义SPI引脚、创建自定义SPI类实例、编写WriteFile与ReadFile函数进行文件读写。setup函数初始化串口、SPI、SD卡&#xff0c;向“/test.txt”写入“myfirstmessage”&#xff0c;读取并打印其内容。loop函数留空待扩展。 1. 需要…

Lock-It for Mac(应用程序加密工具)

OSXBytes Lock-It for Mac是一款功能强大的应用程序加密工具&#xff0c;专为Mac用户设计。该软件具有多种功能&#xff0c;旨在保护用户的隐私和数据安全。 Lock-It for Mac v1.3.0激活版下载 首先&#xff0c;Lock-It for Mac能够完全隐藏应用程序&#xff0c;使其不易被他人…

PCV库之调用SIFT.py中process_image()执行错误的解决方案

背景介绍: windows10,python3.x,64位AMD R9处理器,ROG电脑,pycharm开发,已经安装好了PCV库 如何安装PCV库 请看我的博客Python之PCV库安装教程以及解说-CSDN博客文章浏览阅读111次&#xff0c;点赞5次&#xff0c;收藏3次。GitHub - Ultravioletrayss/PCVfile: 文档内含有pyt…

Nginx 配置 SSL(HTTPS)详解

Nginx作为一款高性能的HTTP和反向代理服务器&#xff0c;自然支持SSL/TLS加密通信。本文将详细介绍如何在Nginx中配置SSL&#xff0c;实现HTTPS的访问。 随着互联网安全性的日益重要&#xff0c;HTTPS协议逐渐成为网站加密通信的标配。Nginx作为一款高性能的HTTP和反向代理服务…

OpenCV 实现霍夫圆变换

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV实现霍夫变换 下一篇:OpenCV 实现重新映射 目标 在本教程中&#xff0c;您将学习如何&#xff1a; 使用 OpenCV 函数 HoughCircles()检测图像中的圆圈。 理论 Hough 圆变换 H…

Cgicc搭建交叉编译环境(移植到arm)

Cgicc GUN Project官网连接&#xff1a;Cgicc- GNU Project - Free Software Foundation 1. 下载源码 Cgicc下载地址&#xff1a; [via http] Index of /gnu/cgicc [via FTP] ftp://ftp.gnu.org/gnu/cgicc/ 目前最新版&#xff1a;3.2.20 2. 源码构建原理 一般&#xff…

在VSCode中调试其他软件执行的python文件

在VSCode中调试其他软件执行的python文件 0. 实际场景 我有一段python代码想在Metashape中运行&#xff0c;但是又想在中间某一步停下来查看变量值。由于Metashape的python环境不容易在vscode中配置&#xff0c;所以直接用vscode调试单个文件的方式无法实现这个想法。还好&am…

42. UE5 RPG 实现火球术伤害

上一篇&#xff0c;我们解决了火球术于物体碰撞的问题&#xff0c;现在火球术能够正确的和攻击目标产生碰撞。接下来&#xff0c;我们要实现火球术的伤害功能&#xff0c;在火球术击中目标后&#xff0c;给目标造成伤害。 实现伤害功能的思路是给技能一个GameplayEffect&#x…

3DTiles生产流程与规范

一篇19年整理的比较老的笔记了。更多精彩内容尽在数字孪生平台。 瓦片切分 标准的四叉树切分对于均匀分布的地理数据切片非常有效&#xff0c;但是这样均等的切分不适用于随机分布、不均匀分布的地理数据&#xff0c;当地理数据稀疏分布的时候&#xff0c;均等的四叉树就不再高…

跟着Datawhale重学数据结构与算法(3)---排序算法

开源链接&#xff1a;【 教程地址 】【电子网站】 【写博客的目的是记录自己学习过程&#xff0c;方便自己复盘&#xff0c;专业课复习】 数组排序&#xff1a; #mermaid-svg-F3iLcKsVv8gcmqqC {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16p…

PHP项目搭建与启动

1、拉取项目 2、安装phpstudy 下载地址&#xff1a; Windows版phpstudy下载 - 小皮面板(phpstudy) (xp.cn) 软件安装&#xff1a; Apache2.4.39、Nginx1.15.11、MySQL8.0.12、 composer2.5.8 添加伪静态 将下面代码写入到伪静态配置文本域框内&#xff1a; location ~* (ru…

【Qt 学习笔记】Qt常用控件 | 输入类控件 | Text Edit的使用及说明

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 输入类控件 | Text Edit的使用及说明 文章编号&#xff…

VScode使用cmake编译

一&#xff1a;输入 ctrlshiftp打开用于命令执行的输入框 二&#xff1a;输入cmake&#xff0c;选择quick start 模式 三&#xff1a;选择版本最高的gcc版本 四&#xff1a;输入项目名称 选择C 五&#xff1a;选择executable 这样便创建好了最简单的cmake例程&#xff0c;一个…