【机考】华为OD2022.11.01机考题目思路与代码

news/2024/4/26 7:56:57/文章来源:https://blog.csdn.net/qq_24052051/article/details/127672755

题目一

描述

输入一个长度为4的倍数的字符串,字符串中仅包含WASD四个字母。

将这个字符串中的连续子串用同等长度的仅包含WASD的字符串替换,如果替换后整个字符串中WASD四个字母出现的频数相同,那么我们称替换后的字符串是“完美走位”。

求子串的最小长度。

示例

输入:
WASDAASD输出:
1说明:
将第二个A替换为W,即可得到完美走位  
输入:
AAAA输出:
3说明:
将其中三个连续的A替换为WSD,即可得到完美走位  

思路与代码

这题我并没有AC,用例通过率95.45%,确定是效率问题,经过改进后时间复杂度从O(n3)降低为O(n2)。

首先确定一下如何判断一个子串被替换后可以让整个字符串变成“完美走位”。

假设要替换的子串长度为m,子串前长度n1,子串后长度n2,:

image.png

在最开始,用HashMap统计整个字符串中WASD的出现频数,得到map

然后用HashMap统计m子串中WASD的出现频数,得到insideMap

用map各个键的值减去insideMap中对应键的值,可得n1+n2中WASD频数映射,写回insideMap

找到insideMap中最大的值,乘四然后减去所有值的和,就是替换m后成为完美走位需要的m的长度needSteps

如果m的长度大于等于needSteps,m经过替换后整个字符串可以成为完美走位。

最简单的方式就是暴力枚举,检查各个m是否符合要求,取最短的m的长度,即可得到答案:

/*** 求需要替换的最小连续走位长度* 完美走位:WASD四个字母出现次数相同* 输入步数为4的倍数*/
public class P1 {private static Scanner scanner=new Scanner(System.in);public static void main(String[] args) {String str=scanner.nextLine();//获取字符串本身的统计信息HashMap<Character,Integer> map=getAmountMap(str);//如果已经是完美走位,输出0,不检查if(map.get('A')==map.get('S')&&map.get('S')==map.get('W')&&map.get('W')==map.get('D')){System.out.println(0);return;}//记录已知的可行最小替换长度int minLen=str.length();//对每一个字母开头的序列进行检查for(int i=0;i<str.length();i++){//对每一个字母开头往后长度小于等于minLen的序列,检查可否替换后形成完美走位for(int j=0;j<minLen&&i+j<str.length();j++){//获取这段字符串中的统计HashMap<Character,Integer> insideMap=getAmountMap(str.substring(i,i+j+1));//得到源字符串减去字串后其他部分(外串)的统计信息insideMap.put('A',map.get('A')-insideMap.get('A'));insideMap.put('S',map.get('S')-insideMap.get('S'));insideMap.put('W',map.get('W')-insideMap.get('W'));insideMap.put('D',map.get('D')-insideMap.get('D'));//获取外串需要多少步来补(这里可以优化,对字符串中所有元素,建立两个map,其中对应map记录了每个元素左边和右边的统计信息)int needSteps=getNeedSteps(insideMap);//如果子串长度可以用于补足外串的差,那就可行if(needSteps==j+1){minLen=j+1;}}}System.out.println(minLen);}/*** 获取需要多少步来补* @param insideMap* @return*/private static int getNeedSteps(HashMap<Character, Integer> insideMap) {//获取四个步int a=insideMap.get('A');int s=insideMap.get('S');int d=insideMap.get('D');int w=insideMap.get('W');//获取最长的步int max=s;if(max<d){max=d;}if(max<w){max=w;}if(max<a){max=a;}return max*4-a-s-d-w;}/*** 获取一个字符串中四个字母的数量映射* @return*/private static HashMap<Character,Integer> getAmountMap(String str){//统计出wasd在字符串中各自的数量HashMap<Character,Integer> map=new HashMap<>();map.put('A',0);map.put('S',0);map.put('W',0);map.put('D',0);char c;for(int i=0;i<str.length();i++){c=str.charAt(i);map.put(c,map.get(c)+1);}return map;}
}

上述代码把统计子串WASD频数的操作放到了两个for循环中,而统计子串WASD本身时间复杂度为O(n),因此整体时间复杂度上升到o(n^3)。

因为我们其实不需要知道子串中WASD频数,只要知道n1和n2的WASD频数,所以可以把统计频数的操作放到main函数中for循环的外部,记录下所有位置左边和右边WASD频数映射,到时候在两个for循环内直接取值即可:

/*** 求需要替换的最小连续走位长度* 完美走位:WASD四个字母出现次数相同* 输入步数为4的倍数* 优化时间复杂度为O(n^2)*/
public class P1_AD {private static Scanner scanner=new Scanner(System.in);public static void main(String[] args) {String str=scanner.nextLine();//获取字符串本身的统计信息HashMap<Character,Integer> map=getAmountMap(str);//如果已经是完美走位,输出0,不检查if(map.get('A')==map.get('S')&&map.get('S')==map.get('W')&&map.get('W')==map.get('D')){System.out.println(0);return;}//统计字符串中每个位置左边和右边WASD频数列表ArrayList<HashMap<Character,Integer>> leftMap=new ArrayList<>();ArrayList<HashMap<Character,Integer>> rightMap=new ArrayList<>();for (int i = 0; i < str.length(); i++) {leftMap.add(getAmountMap(str.substring(0,i)));rightMap.add(getAmountMap(str.substring(i+1)));}//记录已知的可行最小替换长度int minLen=str.length();//对每一个字母开头的序列进行检查for(int i=0;i<str.length();i++){//对每一个字母开头往后长度小于等于minLen的序列,检查可否替换后形成完美走位for(int j=0;j<minLen&&i+j<str.length();j++){//得到源字符串减去字串后其他部分(外串)的统计信息HashMap<Character,Integer> otherMap=new HashMap<>();otherMap.put('A',leftMap.get(i).get('A')+rightMap.get(i+j).get('A'));otherMap.put('S',leftMap.get(i).get('S')+rightMap.get(i+j).get('S'));otherMap.put('W',leftMap.get(i).get('W')+rightMap.get(i+j).get('W'));otherMap.put('D',leftMap.get(i).get('D')+rightMap.get(i+j).get('D'));//获取外串需要多少步来补(这里可以优化,对字符串中所有元素,建立两个map,其中对应map记录了每个元素左边和右边的统计信息)int needSteps=getNeedSteps(otherMap);//如果子串长度可以用于补足外串的差,那就可行if(needSteps==j+1){minLen=j+1;}}}System.out.println(minLen);}/*** 获取需要多少步来补* @param insideMap* @return*/private static int getNeedSteps(HashMap<Character, Integer> insideMap) {//获取四个步int a=insideMap.get('A');int s=insideMap.get('S');int d=insideMap.get('D');int w=insideMap.get('W');//获取最长的步int max=s;if(max<d){max=d;}if(max<w){max=w;}if(max<a){max=a;}return max*4-a-s-d-w;}/*** 获取一个字符串中四个字母的数量映射* @return*/private static HashMap<Character,Integer> getAmountMap(String str){//统计出wasd在字符串中各自的数量HashMap<Character,Integer> map=new HashMap<>();map.put('A',0);map.put('S',0);map.put('W',0);map.put('D',0);char c;for(int i=0;i<str.length();i++){c=str.charAt(i);map.put(c,map.get(c)+1);}return map;}
}

优化后时间复杂度为O(n^2),空间复杂度为O(n)

题目二

描述

在一行中输入一个字符串数组,如果其中一个字符串的所有以索引0开头的子串在数组中都有,那么这个字符串就是潜在密码,在所有潜在密码中最长的是真正的密码,如果有多个长度相同的真正的密码,那么取字典序最大的为唯一的真正的密码,求唯一的真正的密码。

示例

输入:
h he hel hell hello o ok n ni nin ninj ninja输出:
ninja说明:
按要求,hello、ok、ninja都是潜在密码。检查长度,hello、ninja是真正的密码。检查字典序,ninja是唯一真正密码。
输入:
a b c d f输出:
f

思路与代码

已AC

因为在检查是否是潜在密码时需要进行很多次查找操作,所以可以先将所有字符串加入一个HashSet集合,查找字符串时的时间复杂度就降低到O(1)。

然后检查所有字符串是否是密码,对于是密码的,与之前遍历获得的密码比较长度和字典序,取最大的为唯一的真正的密码。

/*** 获取密码*/
public class P2 {private static Scanner scanner=new Scanner(System.in);public static void main(String[] args) {//获取输入的字符串String str=scanner.nextLine();//分割字符串String[] strs=str.split(" ");//将所有字符串放入哈希集合HashSet<String> wordSet=new HashSet<>();for (String s : strs) {wordSet.add(s);}//确认的密码String theWord="";//按顺序检查每一个词for (String s : strs) {//检查这个词是否是密码boolean isWord=true;for(int i=1;i<s.length();i++){String curSubStr=s.substring(0,i);if(!wordSet.contains(curSubStr)){isWord=false;break;}}//符合密码条件,则进一步检查if(isWord){//如果比之前密码更长,保留当前密码if(s.length()>theWord.length())theWord=s;//如果和之前密码长度一样,并且字典排序更大,也保留当前密码if(s.length()==theWord.length()&&s.compareTo(theWord)>0){theWord=s;}}}//输出结果System.out.println(theWord);}
}

时间复杂度O(n^2)

题目三

描述

简化版羊、狼、农夫过河。

羊、狼、农夫都在岸边,农夫有一艘容量固定的船,要求求出不损失羊情况下将全部羊和狼运到对岸需要的次数。

农夫在或农夫离开后羊的数量大于狼的数量时狼不会攻击羊。

只计算农夫去对岸的次数,回程时农夫不会运送羊和狼。

示例

输入:
5 3 3输出:
3说明:
第一次运2只狼
第二次运3只羊
第三次运2只羊和1只狼
输入:
5 4 1输出:
0说明:
如果找不到不损失羊的运送方案,输出0

思路与代码

使用递归和深度优先搜索,对每一种不损失羊的情况进行检查,即农夫离岸后羊比狼多,若找到比记录下来的次数更少的方案,记下来,最后输出结果。

/*** m只羊、n只狼、x容量* 农夫在或羊比狼多时,狼不会攻击,离岸时*/
public class P3 {/*** 运输时*  出发的一边,岸上的羊要比狼多*  船上只要不超出容量即可*  送到的**/private static Scanner scanner=new Scanner(System.in);//记录最少运输次数private static int minTimes=Integer.MAX_VALUE;public static void main(String[] args) {String str=scanner.nextLine();String[] strs=str.split(" ");int m0=Integer.parseInt(strs[0]);//羊int n0=Integer.parseInt(strs[1]);//狼int x=Integer.parseInt(strs[2]);//船int m1=0;int n1=0;getTransportTime(m0,n0,x,m1,n1,0);//如果步数等于初始化数字,那么代表没找到运输方法(理论上存在bug,需要优化)if(minTimes==Integer.MAX_VALUE){System.out.println(0);}else{System.out.println(minTimes);}}/*** 递归查找可行方案* @param m0* @param n0* @param x* @param m1* @param n1* @param times* @return*/private static int getTransportTime(int m0, int n0, int x, int m1, int n1,int times) {//若可以一次性运走,结束了,注意等于号。。。if(x>=m0+n0){if(times+1<minTimes){minTimes=times+1;}return times+1;}//尝试运一部分狼一部分羊//要上船的羊数量不可以超过岸上数量、也不可以超过船的容量for(int i=0;i<=m0&&i<=x;i++){//要上船的狼的数量不可以超过岸上数量、也不可以超过船装了羊后的剩余的容量for(int j=0;j<=n0&&i+j<=x;j++){//不可以不运if(i+j==0){continue;}//船离岸后,原来这岸,要么没有羊,要么羊比狼多,才可以运;对岸也要检查,不考虑回程带动物if((m0-i==0||m0-i>n0-j)&&(m1+i==0||m1+i>n1+j)){//运一次int result=getTransportTime(m0-i,n0-j,x,m1+i,n1+j,times+1);//如果获取了结果,和minTime比较,但是不结束,继续检查if(result<minTimes&&result!=0){minTimes=result;}}}}//没有方案了。。返回0return 0;}
}

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

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

相关文章

【linux】shell脚本 循环 echo输入输出 函数 shell调试

1.循环 for/do/done shell脚本的for循环结构和C语言不一样&#xff0c;它类似于某些编程语的foreach循环。 #!/bin/bash for FRUIT in apple banana pear; doecho "I like $FRUIT" doneFRUIT&#xff08;可自定义变量&#xff09;是一个循环变量&#xff0c;第一次循…

如何发表计算机SCI或者EI论文? - 易智编译EaseEditing

首先是期刊的选择 1、期刊档次 自己文章的水平自己应该是非常清楚的&#xff0c;也可以请导师帮忙评估文章的创新性和研究价值&#xff0c;选定一个适合文章发表的期刊范围。 2、期刊的领域偏好 不同的期刊尽管有时已经给出了自己的发表文章的领域&#xff0c;但是你只要认真…

python基于PHP+MySQL的在线音乐点歌系统

音乐是人们永恒的追求。自古有以来就有语音绕梁三日的佳话,由此几千年来我国人民对音乐的重视程度。为了让音乐得到更好的传播,让更多的人能够听到美妙的音乐。我们开发了PHP在线音乐点歌系统 PHP在线音乐点歌系统是一个音乐爱好者的乐土,本系统采用PHP&#xff1a;MySQL进行开…

Android开发使用Room(SQLite封装)操作数据库

一、Room介绍 Android采用Sqlite作为数据库存储。Sqlite代码写起来繁琐且容易出错&#xff0c;所以开源社区里逐渐出现了各种ORM&#xff08;Object Relational Mapping&#xff09;库。这些开源ORM库都是为了方便Sqlite的使用&#xff0c;包括数据库的创建&#xff0c;升级&am…

【计组 期末版】1.计算机系统概论(一)勇闯期末考试

【计组 期末版】1.计算机系统概论&#xff08;一&#xff09;搞定期末 前言 博主主页&#xff1a;潮.eth的博客_CSDN博客-C学习,C学习,数据结构and算法领域博主 文章目录&#xff1a;【计组 期末版】计算机组成原理笔记目录 正文 文章目录【计组 期末版】1.计算机系统概论&…

Java NIO 关键概念之 Buffer

一、前言 Java NIO 的三大关键概念之一是 Buffer&#xff0c;在一些文章/源代码中&#xff0c;我们也经常会看到 Buffer 相关的信息。Buffer 到底是什么&#xff0c;Buffer 的基本使用方法是什么&#xff0c;这是本文主要要说的。 二、Buffer 的基本概念 Buffer自 JDK1.4 引…

快速教你如何搭建数据驱动自动化测试框架?

一、前言 说到数据驱动自动化测试&#xff0c;你会不会有这样的疑问&#xff1a;数据怎么管理&#xff1f;数据怎么才能驱动测试用例执行&#xff1f;到底怎么样才算数据驱动&#xff1f;那么本篇文章就教你如何进行数据驱动测试&#xff0c;相信你一定能对数据驱动自动化测试…

拓端tecdat|R语言向量自回归模型(VAR)及其实现

全文链接&#xff1a;http://tecdat.cn/?p6916 原文出处&#xff1a;拓端数据部落公众号 澳大利亚在2008 - 2009年全球金融危机期间发生了这种情况。澳大利亚政府发布了一揽子刺激计划&#xff0c;其中包括2008年12月的现金支付&#xff0c;恰逢圣诞节。因此&#xff0c;零售…

巧妙使用多个旧路由器无线中继提升网络速度

巧用多个路由器进行无线桥接或无线中继&#xff0c;提升网络速度 一、设备选择 1、百兆旧路由器&#xff0c;3-4个&#xff0c;用于无线中继WIFI信号&#xff0c;输出给多WAN路由器&#xff08;DI-8200&#xff09; 历史遗留百兆旧路由器3个&#xff0c;型号分别为腾达FH456…

3、用手机模拟器上的Autojs连接电脑vscode

文章目录1、下载模拟器2、在模拟器上安装Autojs3、连接vscode1、下载模拟器 这里推荐雷电模拟器 https://www.ldmnq.com/?n6005 2、在模拟器上安装Autojs 3、连接vscode 打开autojs打开侧边栏&#xff0c;然后选择连接电脑&#xff0c;打开服务器模式然后复制这个IP地址 4.…

浅谈 Mybatis 动态数据源切换是如何实现的

前言 小憩是辣么的让人神往&#xff0c;就像备战高考靠窗位置的那个你&#xff0c;肆无忌道的放空自己&#xff0c;望着深蓝色宁静的天空&#xff0c;思考着未来该何去何从&#xff0c;近处一颗高大魁梧的银杏树在炎炎夏日中尽情的摇曳着自己嫩绿的枝丫&#xff0c;迸发出无尽的…

计算机毕业设计ssm+vue基本微信小程序的高速公路服务区充电桩在线预订系统 uniapp 小程序

项目介绍 随着网络技术的发展,当前人们的生活模式发生了巨大的变化,特别是以电子商务为代表的产业影响了人们的生活。当前,电子商务成为振兴国家经济的重要手段,电子商务为人们的生活提供了极大的便利,帮助企业降低销售成本,提高销售效率。高速公路服务区作为传统的实体行业,经…

BGP BFD测试案例

一、BFD原理 1.1 BFD技术简介 一种全网统一、检测迅速、监控网络中链路或者IP路由的双向转发连通状况&#xff0c;并未上层应用提供服务的技术。 1.2 BFD会话建立方式和监测机制 ●BFD的标识符&#xff1a; &#xff08;1&#xff09;BFD建立会话存在标识符的概念&#xff…

中小企业数字化思考:数字化转型应该走自己的路

随着数字化的发展&#xff0c;以及数字中国概念的形成&#xff0c;和以前国央企宣布数字化转型时的不同&#xff0c;现在越来越多的企业开始寻求数字化转型&#xff0c;促使自身业务能够更好的发展。现在看过去&#xff0c;各行各业都有大量企业进行了数字化转型规划&#xff0…

【Mac】VSCode 更新1.73版本后JSTS代码跳转异常

前言 今天有小伙伴MacOS更新了VS Code版本后&#xff0c;说工程内的代码跳转全部异常了&#xff0c;没法正确跳转。搞了两三个小时没搞出来&#xff0c;找到了我&#xff0c;让我帮忙瞧瞧。排查下来发现这问题有点意思&#xff0c;故此记录一下。 问题 排查姿势 1. 提示没有定…

Skywalking9.2.0监控浏览器

Skywalking9.2.0监控浏览器 安装skywalking-client-js npm install skywalking-client-js --save在main.js添加信息 import ClientMonitor from skywalking-client-jsrouter.afterEach(() > {ClientMonitor.setPerformance({service: 服务名,serviceVersion: 版本号,pagePat…

基于模糊小波神经网络的空中目标威胁评估(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 在现代战争中, 随着信息化和智能化的飞速发展, 以及作战环境的日益复杂, 实时而准确地评估目标威胁, 不仅为空战决策提供科学的…

程序人生:技术水平低,就这还敢写自动化项目实战经验丰富?

今年部门要招两个自动化测试&#xff0c;这几个月我面试了几十位候选人。发现一个很奇怪的现象&#xff0c;面试中一问到元素定位、框架api、脚本编写之类的&#xff0c;很多候选人都对答如流。但是一问到实际项目&#xff0c;比如 “如何从0开始搭建自动化体系”、“如果让你来…

资深大牛纯手写RabbitMQ 核心笔记,还有谁?

RabbitMQ简介 RabbitMQ是消息代理(Message Broker)&#xff0c;它支持多种异步消息处理方式&#xff0c;最常见的有&#xff1a; Work Queue&#xff1a;将消息缓存到一个队列&#xff0c;默认情况下&#xff0c;多个worker按照Round Robin的方式处理队列中的消息。每个消息只…

CART回归树算法

【题目1】 表1为拖欠贷款人员训练样本数据集,使用CART算法基于该表数据构造决策树模型,并使用表2中测试样本集确定剪枝后的最优子树。 表1 拖欠贷款人员训练样本数据集编号 房产状况 婚姻情况 年收(千元) 拖欠贷款1 是 单身 125 否2 否 已婚 100 否3 否 单身 70 否4 是 已婚…