2024.5.28晚训题解

提前预告,市赛初中组会考算法题,应该会有两道模板题
比如DFS BFS 二分 简单动态规划,虽然我们没学多久,但是模板题你还是要会写的

A题 编辑距离 动态规划
注意多组输入

#include<iostream>
using namespace std;
int dp[1005][1005];
//dp[i][j]把s字符串的前i个经过一系列操作变成b字符串的前j个的最小代价 
char s[1005];
char b[1005];
int main(){
	int n,m;
	while(scanf("%d%s%d%s",&n,s+1,&m,b+1)!=EOF){
		for(int i=0;i<=m;i++){
			dp[0][i]=i; //插入 
		}
		for(int i=0;i<=n;i++){
			dp[i][0]=i; //删除 
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(s[i]==b[j])dp[i][j]=dp[i-1][j-1];//此时i j位置相同,可以直接从s[i-1]->b[j-1] 转移过来
				else{
					dp[i][j]=min(dp[i-1][j-1]+1,min(dp[i-1][j]+1,dp[i][j-1]+1));
					/*
					dp[i-1][j]+1 表示我们把s[1~i] 删掉i位置,得到s[1~i-1]  从它变到b[1~j]  
						dp[i][j-1]+1 表示我们把s[1~i]  从它变到b[1~j-1]  然后插入一个b[j] 
							dp[i-1][j-1]+1    从s[1~i-1]  从它变到b[1~j-1]   对于s[i] 直接修改为b[j]   
					*/
				} 
			}
		}
		printf("%d\n",dp[n][m]);
	}
	return 0;
}

B题 最长上升子序列 (N^2)版本

#include<iostream>
using namespace std;
int A[1005];
int dp[1005]; //dp[i]表示以A[i]结尾的最长上升子序列元素 
int main(){
    int n;
    scanf("%d",&n);
    int ans=1;
    for(int i=1;i<=n;i++){
    	dp[i]=1;
		scanf("%d",&A[i]);
    	for(int j=i-1;j>=1;j--){
    		if(A[j]<A[i]){
    			dp[i]=max(dp[i],dp[j]+1);
			}
		}//考虑拼接的方法,想寻得dp[i],往前面找,跟某个元素拼接起来  形成以A[i]
		//结尾的上升子序列,那么所有的子序列取max也就是最大的   
		ans=max(ans,dp[i]);//但是答案不一定是以A[n]结尾  
	}
	printf("%d",ans);
	return 0;
}

当然,其实还有优化写法,利用二分,即可实现NlogN 的时间复杂度
我建议还是背一下(理解一下)
代码不是完全的,请看看思路

ll dp[N];
ll a[N];
ll b[N];
signed  main() {
	ll n;
	read(n);
	for(int i=1; i<=n; i++) {
		read(a[i]);
	}
	ll cnt=0;
	for(int i=1; i<=n; i++) {
		if(cnt==0||a[i]>dp[cnt]) {
			dp[++cnt]=a[i];//首位置要放入元素
			//如果当前元素A【i】比当前序列结尾的还要大,放进来  上升 
			continue;
		} else {
		    //如果当前元素A[i]≤ 序列结尾  
		    //考虑查找序列里面合适的值,替换掉 
		    //举例  1 100 2   
		    //实际上用2替换100会更优,因为你过程的元素越大,越不利于后续上升
			dp[upper_bound(dp+1,dp+1+cnt,a[i])-dp]=a[i];
		}
	}
	printf("%lld",cnt);
}

右边的数字即全球通过人数
在这里插入图片描述

C题题解
我觉得这是不能错的题。 1 ∗ 1 1*1 11的格子不用说了,啥地方都能放
主要看 2 ∗ 2 2*2 22的,一个板只能放最多两个 2 ∗ 2 2*2 22
所以你要先计算出放 b b b 2 ∗ 2 2*2 22的要多少板 ,以及这些板还有多少个格子没放的。
如果多余没放的格子足够放完 a a a 1 ∗ 1 1*1 11的 ,那么答案就是 2 ∗ 2 2*2 22需要的板子数
否则你还需要用(a-多余格子) 这么多个格子去计算还需要多少块板

#include<bits/stdc++.h>
using namespace std;
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
	int a,b;	
	scanf("%d%d",&a,&b);	
	int le=0;
	if(b%2==0)le=(15-8)*(b/2);
	if(b%2){
		le=(15-8)*(b/2)+15-4;
	}
	int ans=b/2+b%2;
	if(a<=le)printf("%d\n",ans);
	else{
	 	printf("%d\n",ans+(a-le)/15+((a-le)%15!=0));	
	}
	}
	return 0;
}

D题题解
这其实就是个简单的模拟题,你把输入的字符串字母sort一遍,把密码表处理出来
然后枚举字符串开始翻译就行了

#include<bits/stdc++.h>
using namespace std;
char s[200005];
char b[30];
bool vis[30];
char sw[30];
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		memset(vis,false,sizeof(vis));
		int n;
		scanf("%d",&n);
		scanf("%s",s+1);
		int len=0;
		for(int i=1;i<=n;i++){
			if(vis[s[i]-'a'])continue;
			else{
				vis[s[i]-'a']=true;
				b[++len]=s[i];
			}
		}
		sort(b+1,b+1+len);
		for(int i=1;i<=len/2+1;i++){
			sw[b[i]-'a']=b[len-i+1];
			sw[b[len-i+1]-'a']=b[i];
		}
		for(int i=1;i<=n;i++){
			s[i]=sw[s[i]-'a'];
		}
		printf("%s\n",s+1);
	}
	return 0;
}

E题题解
这个标记题需要一定数理知识
对于一个三元组 A [ i − 2 ] , A [ i − 1 ] , A [ i ] {A[i-2],A[i-1],A[i]} A[i2],A[i1],A[i] 我们得标记它们,你可以想象一下,什么样的三元组能相互之间算答案?有两个元素一样对不对,我们直接把一样的元素标记起来,记为一个二元组。

以此标记该三元组里面的二元组,按顺序标记
每次计算答案的时候,查找一下当前三元组前面,有多少个跟自己的二元组一样的三元组,该操作不保证过滤了重复元素
因此我们需要查询该三元组前面有多少个跟自己一模一样的三元组,因为一模一样是不会产生答案的,所以要减去3倍

#include<bits/stdc++.h>
using namespace std;
int A[200005];
map<pair<int,int>,int >vis_1;
map<pair<int,int>,int >vis_2;
map<pair<int,int>,int >vis_3;
map<pair<pair<int,int>,int> ,int >pre;
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int n;
		scanf("%d",&n);
		long long int ans=0;
		for(int i=1;i<=n;i++){
			scanf("%d",&A[i]);
			if(i>=3){
			//    当前三元组A[i-2] A[i-1] A[i] 
			  //  三种可能: A[i-2]A[i]相等   A[i-1]A[i]相等   A[i-2]A[i-1]相等  这三个二元组可以作为标记去查询
			    
				ans=ans+vis_1[make_pair(A[i-2],A[i-1])];
				//统计前面有多少个跟A[i-2] A[i-1]值一样的二元组(先不考虑前面存在跟自己完全一样的三元组,那么答案就是加这个二元组标记的个数,视作前面出现的该二元组的元素与当前A[i]都不一样)
				//A[i-2] A[i-1]   ?        前面的一些三元组结构
				//A[i-2] A[i-1] A[i]       当前三元组    
				ans=ans+vis_2[make_pair(A[i-2],A[i])];
				ans=ans+vis_3[make_pair(A[i-1],A[i])];	
				vis_1[make_pair(A[i-2],A[i-1])]++;
				vis_2[make_pair(A[i-2],A[i])]++;
				vis_3[make_pair(A[i-1],A[i])]++;
				ans=ans-3*pre[make_pair(make_pair(A[i-2],A[i-1]),A[i])];
				//考虑存在重复的问题,举例
				//如果前面有x个三元组满足值与当前三元组(A[i-2],A[i-1],A[i])一样,那么我们就多计算了x个答案,因为完全相等的三元组不产生答案贡献,枚举了三个二元组,所以减法要减去*3  
				pre[make_pair(make_pair(A[i-2],A[i-1]),A[i])]++;
			}
		}
		printf("%lld\n",ans);
		vis_1.clear();
		vis_2.clear();
		vis_3.clear();
		pre.clear();
	}
	return 0;
}

F题题解
考虑东西南北指令,划分为两部分
一个部分是: 北南凑一对,相当于抵消移动 东西凑一对,相当于抵消移动

第一部分完成后,未凑对的剩下来的只能是北/南里面的一种,剩下的我们要考虑能不能均分给两个人,同理东西

计算北南的对数,东西的对数
北南可以按A人先的顺序轮流分配
东西可以按B人先的顺序轮流分配
接下来分配剩余的未配对的,注意如果剩余奇数个,肯定不能保证最终两个人走在同一个地方

#include<bits/stdc++.h>
using namespace std;
char s[200005];
int vis[30];
int A[30];
int B[30];
int main(){
	int t;
	scanf("%d",&t);
	int N,S,E,W;
	N='N'-'A';
	S='S'-'A';
	E='E'-'A';
	W='W'-'A';
	while(t--){
		int n;
		scanf("%d",&n);
		scanf("%s",s+1);
		vis[N]=vis[S]=vis[E]=vis[W]=0;
		A[N]=A[S]=A[E]=A[W]=0;
		B[N]=B[S]=B[E]=B[W]=0;
		for(int i=1;i<=n;i++){
			vis[s[i]-'A']++;
		}
		int ns=min(vis[N],vis[S]);
		int ew=min(vis[E],vis[W]);//配对相消  
		int lens=max(vis[N],vis[S])-min(vis[N],vis[S]);
		int leew=max(vis[E],vis[W])-min(vis[E],vis[W]); 
		for(int i=1;i<=ns;i++){
			if(i%2){
				A[N]++;
				A[S]++;
			}
			else{
				B[N]++;
				B[S]++;
			}
		}
		for(int i=1;i<=ew;i++){
			if(i%2){
				B[E]++;
				B[W]++;
			}
			else{
				A[E]++;
				A[W]++;
			}
		}
		//双消+偶数
		//单消 + 偶 
		if(lens%2||leew%2){
			printf("NO\n");
			
		}
		else{
			int op;
			if(vis[N]>vis[S])op=N;
			else op=S;
			A[op]+=lens/2;
			B[op]+=lens/2;
			if(vis[E]>vis[W])op=E;
			else op=W;
			A[op]+=leew/2;
			B[op]+=leew/2;
			if((A[N]+A[S]+A[E]+A[W])==0||(B[N]+B[S]+B[E]+B[W])==0){
				printf("NO\n");continue;
			}	
			for(int i=1;i<=n;i++){
				if(A[s[i]-'A']){
					A[s[i]-'A']--;
					printf("R");
				}
				else{
					B[s[i]-'A']--;
					printf("H");
				}
			}
			printf("\n");
		}
	}
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024最新升级Stable Diffusion整合包v4.6版来了,附赠SD电商实战教程

Stable Diffusion无疑是最近最火的AI绘画工具之一&#xff0c;本期设计软件库给大家带来了2024最新升级的v4.6版&#xff01;比之前推送的更加智能、快速和简单 2024全新Stable Diffusion 资料包 新版本使用更方便 独家附赠SD电商实战教程 让你快速上手 资源目录一览 01 新…

数据通信基本概念汇总

1. 数据通信基础 网关: 提供协议转换&#xff0c;路由选择&#xff0c;数据交换的网络设备 报文: 网络中所传递的一个数据单元。 数据载荷: 最终要传递的信息 封装: 给数据载荷添加头部和尾部的过程(形成新的报文) 解封装: 给数据载荷去掉头部和尾部的过程(获取数据载荷) 终端设…

[XYCTF新生赛]-Reverse:你是真的大学生吗?解析(汇编异或逆向)

无壳 查看ida 没有办法反汇编&#xff0c;只能直接看汇编了。 这里提示有输入&#xff0c;输入到2F地址后&#xff0c;然后从后往前异或&#xff0c;其中先最后一个字符与第一个字符异或。这里其实也有字符串的长度&#xff0c;推测应该是cx自身异或之后传给了cx 完整exp&am…

【Go语言入门学习笔记】Part3.指针和运算符、以及基本输入

一、前言 仍然好多和C语言类似&#xff0c;计算机的学生应该是很容易入门这一环节&#xff0c;我还在最后的输入中看到了一些些Java输入的影子&#xff0c;而自动的变量类型推断更是有Python那个味道&#xff0c;正可谓几百家之所长了。 二、学习代码 package mainimport (&q…

AI答题项目,无门槛答题一小时收益30+

朋友们&#xff0c;今天我想和大家探讨一个令人兴奋的副业机遇。你是否曾感觉到日常工作的枯燥乏味&#xff0c;而又渴望找到一种轻松的赚钱方式来增加你的收入&#xff1f;今天我将和你分享的这个项目正是你所期待的。 项目的核心是利用AI技术来回答网上付费用户的问题&…

selenium源码学习

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

蓝桥楼赛第30期-Python-第三天赛题 提取用户输入信息题解

楼赛 第30期 Python 模块大比拼 提取用户输入信息 介绍 正则表达式&#xff08;英文为 Regular Expression&#xff0c;常简写为regex、regexp 或 RE&#xff09;&#xff0c;也叫规则表达式、正规表达式&#xff0c;是计算机科学的一个概念。 所谓“正则”&#xff0c;可以…

order by工作过程和优化

工作过程 order by 是由优化器决定的&#xff0c;如果优化器认为filesort速度快&#xff0c;那么走filesort排序&#xff0c;如果优化器认为索引速度快&#xff0c;那么走索引排序。

【云原生_K8S系列】认识 Kubernetes

在当今数字化转型的浪潮中&#xff0c;企业对于构建高效、灵活的软件架构有了更高的期望。而在这个迅速变化的环境中&#xff0c;容器化技术如雨后春笋般涌现&#xff0c;为解决传统部署和管理软件所带来的挑战提供了一种全新的解决方案。在众多容器编排工具中&#xff0c;Kube…

JavaScript--作用域是什么

作用域是什么 编译原理 在传统的编译语言中&#xff0c;程序中的一段源代码在执行之前会经历三个步骤。成为编译 分词/词法分析 这个过程由字符组成的字符串分解成有意义的代码块&#xff0c;这些代码块成为词法单元。 分词和词法分析之间的主要差异在于词法单元的识别是有…

【网络协议】应用层协议HTTPS

文章目录 为什么引入HTTPS&#xff1f;基本概念加密的基本过程对称加密非对称加密中间人攻击证书 为什么引入HTTPS&#xff1f; 由于HTTP协议在网络传输中是明文传输的&#xff0c;那么当传输一些机密的文件或着对钱的操作时&#xff0c;就会有泄密的风险&#xff0c;从而引入…

项目构建工具maven

一、概述 1、maven是apache的一个开源项目&#xff0c;是一个优秀的项目构建/管理工具 2、apache(软件基金会、非盈利组织、管理维护一些开源项目) 二、功能 1、管理项目中jar包和jar包与jar包之间的依赖 2、完成项目编译、测试、打包 三、核心文件 pom.xml:在里面配置相…

5.28 学习总结

一.CSS学习(一) 一、CSS简介 1、什么是CSS CSS&#xff1a;Cascading Style Sheet 层叠样式表是一组样式设置的规则&#xff0c;用于控制页面的外观样式 2、为什么使用CSS 实现内容与样式的分离&#xff0c;便于团队开发样式复用&#xff0c;便于网站的后期维护页面的精确…

Leecode热题100---二分查找---搜索插入位置

题目&#xff1a; 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 nums 为 无重复元素 的 升序 排列数组 常规思路&#xff1a; class Solution { public:int f…

MySQL--复合查询

之前学过了基本的查询&#xff0c;虽然已经够80%的使用场景了&#xff0c;但是依旧需要了解剩下的20%。 一、多表笛卡尔积&#xff08;多表查询&#xff09; 以前我们使用基本查询的时候&#xff0c;from后面就跟一张表名&#xff0c;在多表查询这里&#xff0c;from后面可以跟…

跟进2年弄丢1.8亿,你的大客管理错在哪里?

数量并非目的之所在&#xff0c;质量才是根本之道。重视1%的超级用户&#xff0c;才是提高效率的关键所在。 ——凯文凯利 在当今的商业环境中&#xff0c;大客户已成为销售服务型企业最宝贵的资产。他们不仅贡献了企业收入的重要一环&#xff0c;…

监管端..

文章目录 1. 登录流程2. 日志AOP 1. 登录流程 使用账号&#xff08;手机号&#xff09;、密码、验证码。登录就是获取token的&#xff0c;输入的账号密码用RSA加密&#xff08;非对称&#xff09; 首先输入账号密码&#xff0c;在发送手机验证码时候先校验账号密码有没有输入…

AI智能体研发之路-模型篇(三):中文大模型开、闭源之争

博客导读&#xff1a; 《AI—工程篇》 AI智能体研发之路-工程篇&#xff08;一&#xff09;&#xff1a;Docker助力AI智能体开发提效 AI智能体研发之路-工程篇&#xff08;二&#xff09;&#xff1a;Dify智能体开发平台一键部署 AI智能体研发之路-工程篇&#xff08;三&am…

kafka-消费者组偏移量重置

文章目录 1、消费者组偏移量重置1.1、列出所有的消费者组1.2、查看 my_group1 组的详细信息1.3、获取 kafka-consumer-groups.sh 的帮助信息1.4、 偏移量重置1.5、再次查看 my_group1 组的详细信息 1、消费者组偏移量重置 1.1、列出所有的消费者组 [rootlocalhost ~]# kafka-…

光伏智慧化运营解决方案的应用和价值

在社会对新能源需求的不断扩大&#xff0c;光伏已经成为了可再生能源的重要组成部分&#xff0c;随着光伏电站数量和规模的不断扩大&#xff0c;相关企业和用户都就开始关注如何能够高效精准的进行电站管理&#xff0c;对此&#xff0c;鹧鸪云提出了光伏智慧化运营解决方案&…