[OJ]平均串问题,存在超时问题未解决

众所周知,两个数a和b的平均数计算公式为(a+b)/2。
实际上平均数也可以描述为:从较小的数依次遍历到较大的数,将遍历的数放入一个列表中,该列表的中心元素。例如:求
3和7的平均数,列表为{3,4,5,6,7},平均数即为中心元素5。
类似的可以定义两个字符串A和B的平均串:设A的字典序小于B,,将由A按字典序生成B依次产生的字符串放入一个集合中,
该集合的中心元素即为平均串。例如求AZ和BF的平均串,按字典序生成的集合为{AZ,BA,BB,BC,BD,BE,BF},取中心元素BC即
为平均串。
给定两个长度相同,内容均为大写字母的字符串s1和s2,s1的字典序小于s2,输出它们的平均串。
在这里插入图片描述
在这里插入图片描述

1.暴力解决方法:使用大量递归,并占用大量内存,罗列每一个数,空间复杂度和时间复杂度极高

import sys
sys.setrecursionlimit(100000000) #例如这里设置为十万 
def main():#code hereglobal s1,s2,ss1=input().strip()s2=input().strip()s=s1if s1.isupper() and s2.isupper() and len(s1)==len(s2) and (len(s1)>=1 and len(s1)<=200000):global newStr,countcount=1newStr=[]newStr.append(s1)meanString(len(s1)-1)if count%2!=0:global meanStrmeanStr=count//2+1#subStr=newStr[1015:]addString(len(s1)-1)print(s)pass#在s1的基础上,加上count//2
def addString(k):global meanStr,sfor i in range(k,-1,-1):while meanStr>1 and s<s2:if i==len(s)-1 and ord(s[i])!=90:meanStr-=1s=s[:i]+s[i].replace(s[i],chr(ord(s[i])+1))+s[i+1:]else:if ord(s[i])!=90:    s=s[:i]+s[i].replace(s[i],chr(ord(s[i])+1))+s[i+1:]i=len(s)-1s=s[:i]+s[i].replace(s[i],chr(ord(s[i])-25))+s[i+1:]meanStr-=1addString(i)elif ord(s[i])==90:addString(i-1)#通过Ascii码进行比较 A=65 Z=90
def meanString(k):global s1,s2,newStr,count#通过首字母,保证s1的字典序小于s2#生成奇数个字符串 if s1<s2:#回溯for i in range(k,-1,-1):#从后往前循环#针对最后一个数while s1<s2: if i==len(s1)-1:                if ord(s1[i])<90:#将最后一个字符串替换                        s1=s1[:i]+s1[i].replace(s1[i],chr(ord(s1[i])+1))+s1[i+1:]count+=1newStr.append(s1)elif ord(s1[i])==90:i-=1meanString(i)breakelif i!=0:            if ord(s1[i])<90:   s1=s1[:i]+s1[i].replace(s1[i],chr(ord(s1[i])+1))+s1[i+1:]i=i+1                 s1=s1[:i]+s1[i:].replace(s1[i],chr(ord(s1[i])-25))i=len(s1)-1 count+=1newStr.append(s1)meanString(i)break                     elif ord(s1[i])==90:i-=1meanString(i)breakelif i==0: if ord(s1[i])<90:s1=s1[:i]+s1[i].replace(s1[i],chr(ord(s1[i])+1))+s1[i+1:] i=i+1                                  s1=s1[:i]+s1[i:].replace(s1[i],chr(ord(s1[i])-25))i=len(s1)-1count+=1 newStr.append(s1)   meanString(i)breakelif ord(s1[i])==90:breakif __name__ == '__main__':main();

运行结果如下:
在这里插入图片描述在这里插入图片描述问题:当字符长度为4时,进行上千次递归,程序出现问题,闪退
在这里插入图片描述
2.规律总结方法:

‘’’
规律总结:
AZ–DF : 1+52+6=59 (count=59)
(Z-Z+1):表示最后一位数,+1表示加上最开始的AZ,这里为1
(D-A-1)*26:表示BA–BZ…CA–CZ,,这里为52
(F-A)+1:表示从DA–DF之间的数,+1表示加上最后的DF这里为6
ABF–DDH:21+624+1352+78+7=2083(count=2083)
(Z-F+1):表示最后一位数ABF–ABZ,+1表示最开始的ABF,这里为21
(Z-B)*26:表示ACA–ACZ…AZA–AZZ,这里为624
(D-A-1)2626:表示BAA–BZZ…CAA–CZZ,这里为1352
(D-A)*26:表示从DAA–DAZ…DCA–DCZ,这里为78
(H-A+1):表示DDA–DDH,+1表示加上最后的DDH,这里为7
AABF–DDBH:21+624+16900+35152+2028+26+8=54759(count=54759)
(Z-F+1):表示最后一位数AABF–AABZ,+1表示最开始的AABF,这里为21
(Z-B)26:表示AACA–AACZ…AAZA–AAZZ,这里为624
(Z-A)2626:表示ABAA–ABZZ…AZAA–AZZZ,这里是16900
(D-A-1)2626
26:表示从BAAA–BZZZ…CAAA–CZZZ,这里是35152
(D-A)2626:表示从DAAA–DAZZZ…DCAAA–DCZZZ,这里是2028
(B-A)*26:表示从DDAA–DDAZ,这里是26
(H-A)+1:表示从DDBA–DDBH,+1表示加上最后的DDBH,这里是8

规律总结: 如果存在长度在2位以上的数,且首位不相等,首位相减大于1(这里D-A),那么count/2,即中心点一定在首位的式子中
例如AABF–DDBH:的中心点,在BAAA到DZZZ之间
如果存在长度在2位以上的数,且首位不相等,首位相减等于1(这里B-A),那么count/2,中心点一定落在第二位的式子中
AZZZ–BBZZ的中心点,在BAAA到BBZZ之间
如果存在长度为2位,且首位不相等,首位相减等于1(这里B-A),那么count/2,中心点一定落在第二位的式子中
AZ–BF的中心点在BA到BF之间

‘’’

'''
规律总结:
AZ--DF : 1+52+6=59 (count=59)
(Z-Z+1):表示最后一位数,+1表示加上最开始的AZ,这里为1
(D-A-1)*26:表示BA--BZ...CA--CZ,,这里为52
(F-A)+1:表示从DA--DF之间的数,+1表示加上最后的DF这里为6
ABF--DDH:21+624+1352+78+7=2083(count=2083)
(Z-F+1):表示最后一位数ABF--ABZ,+1表示最开始的ABF,这里为21
(Z-B)*26:表示ACA--ACZ...AZA--AZZ,这里为624
(D-A-1)*26*26:表示BAA--BZZ..CAA--CZZ,这里为1352
(D-A)*26:表示从DAA--DAZ...DCA--DCZ,这里为78
(H-A+1):表示DDA--DDH,+1表示加上最后的DDH,这里为7
AABF--DDBH:21+624+16900+35152+2028+26+8=54759(count=54759)
(Z-F+1):表示最后一位数AABF--AABZ,+1表示最开始的AABF,这里为21
(Z-B)*26:表示AACA--AACZ...AAZA--AAZZ,这里为624
(Z-A)*26*26:表示ABAA--ABZZ...AZAA--AZZZ,这里是16900
(D-A-1)*26*26*26:表示从BAAA--BZZZ...CAAA--CZZZ,这里是35152
(D-A)*26*26:表示从DAAA--DAZZZ...DCAAA--DCZZZ,这里是2028
(B-A)*26:表示从DDAA--DDAZ,这里是26
(H-A)+1:表示从DDBA--DDBH,+1表示加上最后的DDBH,这里是8规律总结:
如果存在长度在2位以上的数,且首位不相等,首位相减大于1(这里D-A),那么count/2,即中心点一定在首位的式子中
例如AABF--DDBH:的中心点,在BAAA到DZZZ之间
如果存在长度在2位以上的数,且首位不相等,首位相减等于1(这里B-A),那么count/2,中心点一定落在第二位的式子中
AZZZ--BBZZ的中心点,在BAAA到BBZZ之间
如果存在长度为2位,且首位不相等,首位相减等于1(这里B-A),那么count/2,中心点一定落在第二位的式子中
AZ--BF的中心点在BA到BF之间
'''
def main():#code hereglobal s1,s2s1=input().strip()s2=input().strip()if s1.isupper() and s2.isupper() and len(s1)==len(s2) and (len(s1)>=1 and len(s1)<=200000):global newStr,count,current_count,current_str,end_countcount=0current_count=0end_count=0current_str=s1substractString(0,s1,s2)if count%2!=0:        #print(count)global meanStr#在cureent_count的基础上进行计数#即在current_str的基础上进行加法AmeanStr=count//2-current_countaddString(len(s1)-1)print(current_str)pass#在s1的基础上,加上count//2
def addString(k):global current_str,meanStr#从末尾开始加,每当Z时,前一位变为原来的数加1,末尾置为A,例如BAAAfor i in range(k,-1,-1):'''判断meanStr落在哪个范围内如果1<=meanStr<=26,则在BAAA到BAAZ之间如果26+1<=meanStr<=26*26,则在BABA到BAZZ之间如果26*26+1<=meanStr<=26*26*26,则在BBAA到BZZZ之间'''if meanStr>0:if i==len(s1)-1:if  pow(26,len(s1)-(i+1))<= meanStr<=pow(26,len(s1)-i):current_str=current_str[:i]+current_str[i].replace(current_str[i],chr(ord(current_str[i])+meanStr))+current_str[i+1:]breakelif i!=0:while  pow(26,len(s1)-(i+1))+1<= meanStr<=pow(26,len(s1)-i):meanStr-=(pow(26,len(s1)-(i+1)))current_str=current_str[:i]+current_str[i].replace(current_str[i],chr(ord(current_str[i])+1))+current_str[i+1:] if meanStr<pow(26,len(s1)-(i+1))+1:addString(i+1)breakelse:#当i==0时while  pow(26,len(s1)-(i+1))+1<= meanStr<=end_count:meanStr-=(pow(26,len(s1)-(i+1))+1)current_str=current_str[:i]+current_str[i].replace(current_str[i],chr(ord(current_str[i])+1))+current_str[i+1:]if meanStr<pow(26,len(s1)-(i+1))+1:addString(i+1)break pass#需要记录首位的状态和此时计数的状态
def substractString(k,s1,s2):global count,current_count,current_str,end_countfor i in range(k,len(s1)):#s1中从前往后遍历if i==0:if  ord(s2[i])>ord(s1[i]):if ord(s2[i])-ord(s1[i])>1:for j in range(len(s1)-1,-1,-1):#从后往前遍历if j!=i:if j==len(s1)-1:count+=ord('Z')-ord(s1[j])+1#开始时的末尾else:count+=(ord('Z')-ord(s1[j]))*pow(26,len(s1)-1-j)current_count=countcurrent_str=chr(ord(s1[i])+1)+(len(s1)-1)*'A'#首字母加1,除了首字母外都是Acount+=(ord(s2[i])-ord(s1[i])-1)*pow(26,len(s1)-1)#计算首位#首位结束时的countend_count=countelif ord(s2[i])-ord(s1[i])==1:#当首位相差等于1时且2位数以上if len(s1)==2:for j in range(len(s1)-1,-1,-1):#从后往前遍历if j!=i:if j==len(s1)-1:count+=ord('Z')-ord(s1[j])+1#开始时的末尾else:count+=(ord('Z')-ord(s1[j]))*pow(26,len(s1)-1-j)current_count=countcurrent_str=chr(ord(s1[i])+1)+(len(s1)-1)*'A'#首字母加1,除了首字母外都是Acount+=(ord(s2[i])-ord(s1[i])-1)*pow(26,len(s1)-1)#计算首位#首位结束时的countend_count=countelif len(s1)>2:for j in range(len(s1)-1,-1,-1):#从后往前遍历if j!=i:if j==len(s1)-1:count+=ord('Z')-ord(s1[j])+1#开始时的末尾elif j==1:  current_count=countcount+=(ord('Z')-ord(s1[j]))*pow(26,len(s1)-1-j)if ord(s1[i+j])+1<90:current_str=s1[i]+chr(ord(s1[i+j])+1)+(len(s1)-1-j)*'A'#第二个字母加1,除了首字母、第二个字母外都是A#首位结束时的countend_count=countcount+=(ord(s2[i+j])-ord(s1[i+j])-1)*pow(26,len(s1)-1-j)#计算首位else:current_str=chr(ord(s1[i])+1)+(len(s1)-1)*'A'substractString(i+1,s1,s2) break       else:count+=(ord('Z')-ord(s1[j]))*pow(26,len(s1)-1-j)breakelif ord(s1[i])==ord(s2[i]): substractString(i+1,s1,s2)breakelse:breakelif i!=len(s1)-1:count+=(ord(s2[i])-ord('A'))*pow(26,len(s1)-1-i)else:#结束时的末尾count+=ord(s2[i])-ord('A')+1if end_count==0:end_count=countpassif __name__ == '__main__':main();

结果运行如下:直接突破50位长度,最终多少长度这里没有进行计算,但能够满足许多需求
在这里插入图片描述存在超时问题,超出该题的时间限制2m,未解决该问题,或许可以改用C++代码,能够大幅降低时间复杂度
在这里插入图片描述
3.为了找到两个字符串的平均串,我们可以按照字典序生成从第一个字符串到第二个字符串的所有中间字符串,然后找到中间位置的字符串作为平均串。下面是具体的步骤和代码实现:

步骤:

  • 确保字符串s1的字典序小于s2。如果不是,则交换两个字符串以确保条件满足。
  • 初始化一个空集合,用于存储按字典序遍历的所有字符串。
  • 从s1开始,逐步修改每个字符直到变成s2,同时将这些字符串添加到集合中。具体来说,对于s1和s2的每个位置i,从s1[i]开始逐步增加到s2[i],并构建对应的字符串添加到集合中。这样可以保证生成的字符串是字典有序的。
  • 找到集合中的字符串数量N(实际上这将是中间位置之前的字符串数量加上中间位置之后的字符串数量)。由于集合中的字符串是按字典序排序的,所以中间位置的字符串将是平均串。如果集合中的元素数量是奇数,则中间位置就是 (N+1)/2;如果集合中的元素数量是偶数,则中间位置介于 N/2 和 (N+1)/2 之间(即取两个中间位置的平均值)。计算平均串的方式可以是简单地取这两个中间位置的字符串的对应字符的平均值(这实际上不太可能产生有意义的平均串,因为我们处理的是字母而非数字),或者可以通过其他方法确定更合适的平均串。由于这个问题没有明确规定如何平均字母,我们可以假设需要找到中间位置的字符串。因此,我们需要向下取整来确定真正的中间位置。
  • 返回集合中对应中间位置的字符串作为平均串。假设返回的是更接近于末尾的中间位置的字符串(即向下取整的中间位置)。
def average_string(s1, s2):# 确保s1字典序小于s2if s1 > s2:s1, s2 = s2, s1# 构建按字典序排列的字符串集合strings_set = set()for i in range(len(s1)):# 逐步生成从s1到s2的所有可能字符串并添加到集合中for c in range(ord(s1[i]), ord(s2[i]) + 1):  # 使用ord函数获取字符的ASCII值范围遍历字符集temp_str = list(s1)  # 创建s1的副本以避免修改原始字符串temp_str[i] = chr(c)  # 修改副本中的字符以构建新的字符串strings_set.add(''.join(temp_str))  # 将新构建的字符串添加到集合中# 计算中间位置的索引并返回对应的字符串作为平均串middle_index = len(strings_set) // 2  # 计算中间位置索引(向下取整)average_str = list(strings_set)[middle_index]  # 获取中间位置的字符串(转换为列表方便索引)或者直接用二分查找等优化手段获取中间元素的值也可以避免将整个集合转换为列表带来的性能损耗。这里为了简化代码直接使用了列表访问方式。return average_str# 测试函数
print(average_string("AZ", "BF"))  # 输出应为 "BC"

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

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

相关文章

使用Java和Hazelcast实现分布式数据存储

使用Java和Hazelcast实现分布式数据存储 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在分布式系统中&#xff0c;实现高效的数据存储和管理是非常重要的。Hazelcast作为一个内存数据网格(IMDG)&…

2024-06学习笔记

1.事务与数据库链接的占用 如果用Transactional注解&#xff0c;那在第一次与数据库交互的时候&#xff0c;就会打开数据库链接&#xff0c;再整个方法执行完&#xff0c;才会关闭数据库链接。 即使后边用的事务传播是required_new,那之前的事务也是被挂起&#xff0c;不会被…

计算机网络408考研 历年真题解析

计算机网络408考研 历年真题解析&#xff08;有字幕无背景音乐版&#xff09;_哔哩哔哩_bilibili 网络工程师历年真题大汇总 【软考中级】网络工程师历年真题大汇总&#xff01;&#xff01;&#xff01;含电子版||备考必刷||软考真题||逐题精讲||通关上岸||免费分享&#…

静态路由学习笔记

1. 静态路由应用场景 &#xff08;1&#xff09;静态路由由网络管理员手动配置&#xff0c;配置方便&#xff0c;对系统要求低&#xff0c;适用于拓扑结构简单并且稳定的小型网络。 &#xff08;2&#xff09;缺点是不能自动适应网络拓扑的变化&#xff0c;需要人工干预过多。…

day05 Router、vuex、axios

配置 router和vuex需要在创建vue项目的时候&#xff0c;开始的时候选择Manually select features&#xff0c;于是就可以在下一个创建配置讯问中选择router和vuex。 axios则需要执行命令行&#xff1a; npm install axios -S 之后再在需要发送请求的view导入即可。 router…

研发(RD)注意事项 / 复杂项目规划、控制方法 PERT 和 CPM

注&#xff1a;机翻&#xff0c;未校对&#xff0c;去掉了原文中广告。 What Is Research and Development (R&D)? 什么是研发&#xff08;R&D&#xff09;&#xff1f; Investopedia / Ellen Lindner Research and Development An ongoing effort to develop or impr…

springboot中使用knife4j访问接口文档的一系列问题

springboot中使用knife4j访问接口文档的一系列问题 1.个人介绍 &#x1f389;&#x1f389;&#x1f389;欢迎来到我的博客,我是一名自学了2年半前端的大一学生,熟悉的技术是JavaScript与Vue.目前正在往全栈方向前进, 如果我的博客给您带来了帮助欢迎您关注我,我将会持续不断的…

Hive3:Centos7环境部署Hive服务

一、安装说明 1、Hadoop集群情况 3台机器&#xff1a;4G2C、2G2C、2G2C 安装教程&#xff1a;Centos7环境安装Hadoop集群 2、安装MySQL&#xff0c;用于存储Hive的元数据 在102机器上安装MySQL 安装MySQL使用服务器的root账号 3、最后安装Hive 安装hive过程使用服务器的atgu…

【C++】选择结构案例-三目运算符

三目运算符语法格式&#xff1a; 布尔表达式?表达式1:表达式2 运算过程&#xff1a;如果布尔表达式的值为 true &#xff0c;则返回 表达式1 的值&#xff0c;否则返回 表达式2 的值 &#xff08;三目运算符指的是&#xff1f;和&#xff1a;&#xff09; 在这个三目运算符…

postman请求响应加解密

部分接口&#xff0c;需要请求加密后&#xff0c;在发动到后端。同时后端返回的响应内容&#xff0c;也是经过了加密。此时&#xff0c;我们先和开发获取到对应的【密钥】&#xff0c;然后在postman的预执行、后执行加入js脚本对明文请求进行加密&#xff0c;然后在发送请求&am…

【vue/JS】拖拽图片加载图片文件到页面画布等

1、阻止浏览器默认行为事件。 2、声明拖拽的区域&#xff0c;为该区域html标签添加drop拖拽事件。 3、获取拖拽的文件数据列表。 4、循环文件列表并且判断文件类型。 5、最终读取文件后加载图片即可&#xff01;&#xff01; <!DOCTYPE html> <html lang"en…

八股文学习第二天| HTTP请求报文和响应报文是怎样的,有哪些常见的字段?,HTTP有哪些请求方式?,GET请求和POST请求的区别?

1、HTTP请求报文和响应报文是怎样的&#xff0c;有哪些常见的字段&#xff1f; 答&#xff1a; HTTP报文分为请求报文和响应报文。 &#xff08;1&#xff09; 请求报文 请求报文主要由请求行、请求头、空行、请求体构成。 请求行包括如下字段&#xff1a; 方法&#xff08…

【游戏制作】使用Python创建一个完整的2048游戏项目

目录 项目运行展示 项目概述 项目目标 项目结构 安装依赖 代码实现 1. 导入库 2. 创建 Game2048 类 3. 设置UI界面 4. 加载二维码图片 5. 创建菜单 6. 游戏逻辑和功能 7. 运行应用 总结 创建一个完整的2048游戏项目 项目运行展示 项目概述 在这个项目中&#xff…

Mysql中如何实现两列的值互换?给你提供些思路。

文章目录 Mysql中如何实现两列的值互换1、第一感觉此sql应该能处理问题了2、需要一个地方存要替换的值&#xff0c;不然两列搞不定。2.1 加第三列&#xff1f;&#xff08;能解决&#xff0c;但是看起来呆呆&#xff09;2.2 上临时表&#xff08;搞点弯路走走&#xff09; 示例…

【Python】基础学习技能提升代码样例2:小功能块

配合以前两篇文章使用&#xff1a; python易忘操作和小知识点集锦 常用算法模板与知识点 使用 Python 3.x 一、小功能 # 把数字转换为货币字符串 import locale # Set the locale to United States locale.setlocale(locale.LC_ALL, en_US.UTF-8) # Example number amount …

直线与曲线的交点

直线与曲线的交点 在数学和计算机图形学中&#xff0c;计算直线与曲线的交点通常涉及到解方程组的问题。这里以Python为例&#xff0c;介绍如何求解直线与二次曲线&#xff08;如抛物线&#xff09;的交点。 直线与抛物线的交点 假设我们有一条直线 (y mx b) 和一条抛物线 …

法制史学习笔记(个人向) Part5

法制史学习笔记(个人向) Part5 7. 宋朝法律制度 这里强烈推荐B站up主有点意思研究所和嘉佑生宣&#xff0c;宋史看他们基本齐了。 7.1 立法概况 7.1.1 宋刑统&#x1f338; 宋朝建立后不久&#xff0c;太祖赵匡胤即制定颁布了《宋建隆重详定刑统》&#xff0c;简称《宋刑统…

Jenkins 服务搭建以及自动化编译部署

安装环境&#xff1a;Ubuntu22.04 1.首先安装Jenkins 这是 Jenkins 的 Debian 软件包存储库&#xff0c;用于自动安装和升级。 要使用此存储库&#xff0c;请先将密钥添加到系统中&#xff0c;在服务器执行命令&#xff1a; curl -fsSL https://pkg.jenkins.io/debian-stable…

如何在 SpringBoot 中优雅的做参数校验?

一、故事背景 关于参数合法性验证的重要性就不多说了&#xff0c;即使前端对参数做了基本验证&#xff0c;后端依然也需要进行验证&#xff0c;以防不合规的数据直接进入服务器&#xff0c;如果不对其进行拦截&#xff0c;严重的甚至会造成系统直接崩溃&#xff01; 本文结合…

Windows下编译安装Kratos

Kratos是一款开源跨平台的多物理场有限元框架。本文记录在Windows下编译Kratos的流程。 Ref. from Kratos KRATOS Multiphysics ("Kratos") is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, a…