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

蓝桥杯真题——前缀总分、遗迹

蓝桥杯2024年第十五届省赛真题-前缀总分

题目描述

给定 n 个由小写英文字母组成的字符串 s1, s2, · · · , sn ,定义前缀总分为V =∑i<j P(si, sj) ,其中 P(si, sj) 表示 si, sj 的最长公共前缀的长度。

小蓝可以选择其中一个字符串,并修改其中的一个字符。请问修改后前缀总分最大为多少?

输入格式

输入的第一行包含一个正整数 n 。接下来 n 行,每行包含一个字符串 si 。

输出格式

输出一行包含一个整数表示答案。

样例输入

3
aab
bbb
abb

样例输出

5

提示

【样例说明】

将第二个字符串改为 abb ,得分为 P(aab, abb)+P(aab, abb)+P(abb, abb) =1 + 1 + 3 = 5 。

【评测用例规模与约定】

对于 20% 的评测用例,1 ≤ n ≤ 20 ;

对于所有评测用例,1 ≤ n ≤ 200 ,1 ≤ |si| ≤ 200 ,其中 |si| 表示 si 的长度。

代码1:会超时

#include<bits/stdc++.h>
//#define int long long 
using namespace std;

const int N=200+10;

int n;
string s[N];
int m[N][N];//存储字符串之间的相似度 
int score;//存放前缀总分 

//计算任意两个字符串之间的公共前缀长度 
int cal(string s1,string s2)
{
	int j=0,tmp=0;
	while(s1[j]!='\0'&&s2[j]!='\0')
	{
		if(s1[j]!=s2[j])
			break;
		tmp++;
		j++;
	}
	return tmp;
}

//计算所有字符串之间的相似度 
int cal_all()
{
	int sum=0;
	for(int i=1;i<=n;i++)
		for(int j=i+1;j<=n;j++)
		{
			m[i][j]=cal(s[i],s[j]);
			sum+=m[i][j];
			m[i][0]+=sum;
			//具有累加效果,存放第i个字符串与后面所有的字符串的前缀总分 
		}
	return sum;
}

//只对改变的字符与所有其他字符进行计算 
//即只是一部分的计算,所以要加上前面所计算的累加结果
//并且前面所计算的累加结果包含了当前所改变的字符,要注意减去 
int cal_part(int i)
{
	int sum=0;
	for(int j=1;j<=n;j++)
	{
		if(i==j) continue;
		sum+=cal(s[i],s[j]);
		sum+=m[j][0];
		if(j<i)	sum-=m[j][i];
	}
	return sum;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>s[i];
		
	score=cal_all();
	
	//改变字符,遍历所有的可能
	for(int i=1;i<=n;i++)
	{
		for(auto &c:s[i])
		{
			//记录,用于恢复现场 
			for(char ch='a';ch<='z';ch++)
			{
				char tmp=c;
				c=ch;//替换字符 
				int sum=cal_part(i);
				score=max(sum,score);  
				c=tmp;
			} 
			//恢复现场,防止对后面产生影响 
		}
	 } 
	cout<<score<<endl;
	return 0;
}

 蓝桥杯2024年第十五届省赛真题-遗迹

题目描述

小蓝找到了一个外星文明留下来的遗迹,遗迹大门的屏幕上有一个长度为m 的字符串 t 和一个输入框,下面还有一个键盘,键盘为一个长度为 n 的字符串 s ,由一个可以横向移动的指针来敲击键盘,指针可以向左移或向右移,不能移出键盘。

小蓝需要在键盘字符串 s 上先指定指针初始位置然后不断移动指针的位置,过程中通过敲击指针所在的字符来进行输入。然而,指针最多只能移动 L 的距离,小蓝想输入一个尽可能长的一个 t 的前缀,请问他最多能输入多少位。

输入格式

输入的第一行包含三个正整数 n, m, L ,相邻整数之间使用一个空格分隔。

第二行包含一个长度为 n 的字符串 s 。

第三行包含一个长度为 m 的字符串 t 。

输出格式

输出一行包含一个整数表示答案。

样例输入

3 6 5
abc
acbbac

样例输出

5

提示

【样例说明】

初始选择指针位于键盘 abc 上的 a ,输入 acbbac 这 6 个字符分别需要指针移动 0, 2, 1, 0, 1, 2 的距离,而最大移动距离为 5 ,所以最多输入 5 个字符,移动 0 + 2 + 1 + 0 + 1 = 4 的距离。

【评测用例规模与约定】

对于 20% 的评测用例,1 ≤ m ≤ 20;

对于所有评测用例,1 ≤ n ≤ 103 ,1 ≤ m ≤ 105 ,1 ≤ L ≤ 109 且 s, t 中只包含小写字母,且 s 中一定包含所有 t 中出现过的字母,数据保证随机。

思路:

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int MAX=1e10;

int n,m,l;
int res;
string s,t;
vector<int> pos[26];
vector<int> shW(26,0);


signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	cin>>n>>m>>l;
	cin>>s>>t;
	
	for(int i=0;i<n;i++)
		pos[(s[i]-'a')].push_back(i);
	
	for(int i=1;i<m;i++)
	{
		int current=t[i]-'a';
		int past=t[i-1]-'a';
		res=MAX;
		if(current!=past)
		{
			bool flag=false;
			for(auto x:pos[current])
			{
				for(auto y:pos[past])
					res=min(res,shW[y]+abs(x-y));
				shW[x]=res;
				if(res<=l)
					flag=true;
			}
			if(!flag)
			{
				cout<<i<<endl;
				return 0;
			}
		}
	}
	cout<<m<<endl;
	return 0;
}

相关文章:

  • el-table,新增、复制数据后,之前的勾选状态丢失
  • 【深度学习】【目标检测】【Ultralytics-YOLO系列】YOLOV3源码整体结构解析
  • 系统与网络安全------Windows系统安全(11)
  • 【笔记】VS中C#类库项目引用另一个类库项目的方法
  • coze生成流程图和思维导图工作流
  • 【C#知识点详解】Dictionary<TKey,TValue>储存结构详解
  • 初阶数据结构(3)顺序表
  • Electron使用WebAssembly实现CRC-32 STM32校验
  • 爱普生高精度车规晶振助力激光雷达自动驾驶
  • Python基础知识点(函数2)
  • 自用记录 | AI辅助 在线画图工具 使用Mermaid语法(流程图 ER图)
  • 【Kafka基础】Kafka 2.8以下版本的安装与配置指南:传统ZooKeeper依赖版详解
  • 如何拿到iframe中嵌入的游戏数据
  • 2023年蓝桥杯第十四届CC++大学B组真题及代码
  • Linux内核设计——(二)进程调度
  • CMake实战指南一:add_custom_command
  • 手撕算法——宽度优先搜索-BFS
  • Shell脚本编程之正则表达式
  • JS DOM节点增删改查
  • Spring事务传播机制
  • 做班级相册网站的目的意义/培训心得体会万能模板
  • 从事网站开发办理什么个体/网络推广费用一般多少
  • 如何说服老板做网站/谷歌浏览器在线入口
  • 织梦做的网站不能用手机访问/网站推广和优化的原因网络营销
  • 进一步推进网站集约化建设/常用seo站长工具
  • 有后台的网站模板/网络销售怎么学