某大厂笔试(小*的车站的最近距离)

       有一个环形的公路,上面共有n站,现在给定了顺时针第i站到第i+1站之间的距离(特殊的,也给出了第n站到第1站的距离),小*想着沿着公路第x站走到第y站,她想知道最短的距离是多少?

输入描述:

第一行输入一个正整数n,代表站的数量。第二行输入n个正整数ai,前 n-1个数代表顺时针沿看公路走,i站到第i+1站之间的距离:最后一个正整数代表顺时针沿着公路走,第n站到第1 站的距离

第三行输入两个正整数x和y,代表小美的出发地和目的地。

                       1 <=n <=10^5 

                       1<=ai < 10^9

                       1<=x,y<=n

输入:

                   3

                   1 2 2

                   2 3

输出:

                    2

       大厂的笔试永远这么晦涩难懂?刚看到题的时候只能知道它是一道图论问题,题目描述的确实有一点绕,现在让我们来分析一波题的含义:

      假如你现在在车站1,假如你的目的地是车站3,你选择哪条路路径最短?毫无疑问肯定是由车站1直接到车站3路径是最短的,我们可以用眼睛直接观察出来,可是计算机可不能直接得出正确答案?如果你做图论的相关题较多的话,其实你刚看到这道题,心里便会想到这道题,和这题类似的leetcode原题(K 站中转内最便宜的航班),我们今天以讲解leetcode为例,这道题知识稍微在那道题中做了变形就出来了

有 n 个城市通过一些航班连接。给你一个数组 flights ,其中 flights[i] = [fromi, toi, pricei] ,表示该航班都从城市 fromi 开始,以价格 pricei 抵达 toi

现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是找到出一条最多经过 k 站中转的路线,使得从 src 到 dst 的 价格最便宜 ,并返回该价格。 如果不存在这样的路线,则输出 -1

n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]]
src = 0, dst = 2, k = 1
输出: 200
解释: 
城市航班图如下:


 

 其实K站中转内最便宜的航班其实约束条件更多一点,其要找到一条最多经过k站中转的路线

我们这次使用递归来解决这个问题

 由于题目中给出我们这些信息,所以我们就可以根据这些信息去构建邻接表:

          因为我们函数在递归的时候,函数中的参数是我们的起点位置,所以我们因为构造一个to-[from,price]的邻接矩阵

//邻接表的数据结构 
Map<Integer,List<Integer[]>> map=new HashMap<>();//遍历每一个数组,取出对应的元素for(int[] f:flights){//起点int from=f[0];//终点int to=f[1];//两点之间的距离int price=f[2];//如果不包含if(!map.containsKey(to)){map.put(to,new LinkedList<>());}//构建邻接表map.get(to).add(new Integer[]{from,price});}

接下来就是我们寻找起点和终点的最短路径的最短距离

函数标签

//dst指的是当前点   k指的是剩下可以步数
private int dfs(int dst, int k) {}

如果我们的起点正好等于我们的终点,直接返回0(说明已经找到了一条可以到达目的地的路线)

 if(dst==src){return 0;}

如果k==0,说明当前已经不满足题目的要求(没到终点且步数为0),直接返回-1

  if(k==0){return -1;}

 如果当前节点合法,那么就遍历与它直接相邻的节点

 if(map.containsKey(dst)){//遍历邻接表for(Integer[] v:map.get(dst)){//起点int from=v[0];//所需要的花费int price=v[1];//递归下一个节点int sub=dfs(from,k-1);//如果sub不是-1,就说明该路线是合法的if(sub!=-1){//当前节点距离终点的路径=下一个节点距离终点的路径+当前节点距离下一个节点的距离res=Math.min(res,sub+price);}}return res;}

这种递归的方法肯定是超时,所以我们使用记忆化搜索的方式去进行优化

 int[][]memo;memo=new int[n][k+1];
//如果曾经已经计算过,直接返回答案
if(memo[dst][k]!=-88)return memo[dst][k];
 res= res==Integer.MAX_VALUE?-1:res;memo[dst][k]=res;

 

动态规划方式就先不做介绍了,大家下去可以自行试一试

源码如下:

    Map<Integer,List<Integer[]>> map=new HashMap<>();//记忆化数组int[][]memo;//起点int src;//终点int dst;public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) {this.dst=dst;this.src=src;//k表示的节点,我们将结点转换成步数,更利于计算k++;memo=new int[n][k+1];//对记忆化数组进行初始化for(int[] row:memo){Arrays.fill(row,-88);}//构造邻接表for(int[] f:flights){int from=f[0];int to=f[1];int price=f[2];if(!map.containsKey(to)){map.put(to,new LinkedList<>());}map.get(to).add(new Integer[]{from,price});}return dfs(dst,k);}//表示从dst的走k步的最小价格private int dfs(int dst, int k) {if(dst==src){return 0;}if(k==0){return -1;}if(memo[dst][k]!=-88)return memo[dst][k];int res=Integer.MAX_VALUE;if(map.containsKey(dst)){for(Integer[] v:map.get(dst)){int from=v[0];int price=v[1];int sub=dfs(from,k-1);if(sub!=-1){res=Math.min(res,sub+price);}}}res= res==Integer.MAX_VALUE?-1:res;memo[dst][k]=res;return memo[dst][k];}

       我们再来看这道所谓大厂的笔试题:这道题过程跟这个题一模一样,我们只需要将上面这个题中的k这个约束给省略掉,这道题也就出来了

代码如下:

 Map<Integer,List<Integer[]>> map=new HashMap<>();int[]memo;int src;int dst;public int findCheapestPrice(int n, int[][] flights, int src, int dst) {this.dst=dst;this.src=src;memo=new int[n];Arrays.fill(memo,-88);for(int[] f:flights){int from=f[0];int to=f[1];int price=f[2];if(!map.containsKey(to)){map.put(to,new LinkedList<>());}map.get(to).add(new Integer[]{from,price});}return dfs(dst);}private int dfs(int dst) {if(dst==src){return 0;}if(memo[dst]!=-88)return memo[dst];int res=Integer.MAX_VALUE;if(map.containsKey(dst)){for(Integer[] v:map.get(dst)){int from=v[0];int price=v[1];int sub=dfs(from);if(sub!=-1){res=Math.min(res,sub+price);}}}res= res==Integer.MAX_VALUE?-1:res;memo[dst]=res;return memo[dst];}

知识ACM模式下我们的所有参数都需要我们手动的去输入,这点也是比较关键点的因素:

起先我是这样写的:

Scanner scanner=new Scanner(System.in);int n=scanner.nextInt();int[][] nums=new int[n][3];int index=0;//遍历每个数组for(int[] num:nums){while(scanner.hasNextInt()){//给每个数组进行赋值for(int i=0;i<num.length;i++) {if(i==n-1){num[0]=i;num[1]=0;num[2]=scanner.nextInt();}else{num[0]=i;num[1]=i+1;num[2]=scanner.nextInt();}}break;}}int start=scanner.nextInt();int end=scanner.nextInt();

       最后半天一直在死循环,后来发现,每个数组就3个元素,我这个for循环加的位置明显就有问题,所以一直在死循环,所以果断换了一种方式,及时止损

        Scanner scanner = new Scanner(System.in);System.out.print("输入行数:");int n = scanner.nextInt();int m = 3;int[][] nums = new int[n][m];System.out.println("输入二维数组中的值:");//利用双层for循环进行定点输入for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {nums[i][j] = scanner.nextInt();}}System.out.println("输入的二维数组为:");for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {System.out.print(nums[i][j] + " ");}System.out.println();}int start = scanner.nextInt();int end = scanner.nextInt();

我们将测试案例试一试:

        这样很明显示我们手动的输入了数组中的元素,这样很显然是不符合题意的,那么我们这么样输入[1 2 2] 会自动生成[[0,1,1],[1,2,2],[2,0,3]]这个数组呢?我们先来说明它这个数组是是怎么生成的?

 因为我们的数组是从0开始计数的,所以我们应该写成这样

 我们开始ACM输入:

 System.out.println("输入二维数组中的值:");//输入一行时ACM输入while(scanner.hasNextInt()){for(int i=0;i<n;i++){int dist=scanner.nextInt();//如果是最后一个直接指向第一个节点if(i==n-1){int[] num=nums[i];num[0]=i;num[1]=0;num[2]=dist;//不是第一个直接指向后一个节点}else{int[] num=nums[i];num[0]=i;num[1]=i+1;num[2]=dist;}}//这个break记得加,要不就会死循环break;}System.out.println("输入的二维数组为:");for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {System.out.print(nums[i][j] + " ");}System.out.println();}

 

       最后我们这道题也就讲解完了,ACM输入的时候对于很多笔试经验少的同学确实是一个挑战,希望大家刷题的过程中多使用ACM刷题,leetcode的话尽量脱离有提示的工具,最好在网页上进行写

ACM源代码输入:

      Scanner scanner = new Scanner(System.in);System.out.print("输入行数:");int n = scanner.nextInt();int m = 3;int[][] nums = new int[n][m];System.out.println("输入二维数组中的值:");while(scanner.hasNextInt()){for(int i=0;i<n;i++){int dist=scanner.nextInt();if(i==n-1){int[] num=nums[i];num[0]=i;num[1]=0;num[2]=dist;}else{int[] num=nums[i];num[0]=i;num[1]=i+1;num[2]=dist;}}break;}System.out.println("输入的二维数组为:");for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {System.out.print(nums[i][j] + " ");}System.out.println();}int start = scanner.nextInt();//输入的是起点为1,数组的起点为0,所以需要减1start=start-1;int end = scanner.nextInt();end=end-1;

如果有更高的ACM输入的方式或者是解题更妙的技巧,欢迎大家来评论区进行评论!!!

 

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

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

相关文章

小程序商城开发制作

当开发一个商城小程序时&#xff0c;费用是一个非常重要的考虑因素。然而&#xff0c;准确回答这个问题是有一定困难的&#xff0c;因为开发商城小程序的费用取决于多个因素。以下是一些可能影响价格的主要因素&#xff1a; 1. 功能需求&#xff1a;商城小程序的复杂程度和功能…

阻塞队列的安全实现,定时器的安全实现(面试易考),超详细

一、&#x1f49b; 如何实现一个线程安全的阻塞队列 目前&#xff0c;当前代码是循环队列&#xff08;还没有进行改动&#xff09; head和tail的判空判断满两种方法: 1.浪费一个格子&#xff0c;当前走到head的前一个位置&#xff0c;就认为队列满的 2.单独搞一个变量&#xff…

系统架构设计专业技能 · 网络规划与设计(三)【系统架构设计师】

系列文章目录 系统架构设计专业技能 网络规划与设计&#xff08;三&#xff09;【系统架构设计师】 系统架构设计专业技能 系统安全分析与设计&#xff08;四&#xff09;【系统架构设计师】 系统架构设计高级技能 软件架构设计&#xff08;一&#xff09;【系统架构设计师…

手把手带你跑通网站上线全流程(一个简单的HTML和Python服务端完整上线流程)

我将向你介绍如何将一个网站部署到公网&#xff0c;包含完整流程。 前端静态网站 静态网站文件 首先需要准备一个简单的网页文件用于展示页面 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name&quo…

2023深圳杯A题完整代码模型

已更新深圳杯A题全部版本&#xff0c;文末获取&#xff01; 摘要 现代社会&#xff0c;随着生活方式的变化和工作压力的增大&#xff0c;慢性非传染性疾病日益成为威胁公众健康的主要问题。心脑血管疾病、糖尿病、恶性肿瘤及慢性阻塞性肺病等慢性病的发病率呈现出上升趋势。为…

23款奔驰AMG GT50更换原厂运动排气系统,战斗感立马提升了

改装运动排气&#xff0c;原车中控的按键组也是需要更换的。与原车按键相比&#xff0c;只是多了一个排气的控制按键&#xff0c;也正是这个按键&#xff0c;能让车辆可静可怒&#xff0c;安静与怒吼就在一键之间。

linux_常用命令

一、日常使用命令/常用快捷键命令 开关机命令 1、shutdown –h now&#xff1a;立刻进行关机 2、shutdown –r now&#xff1a;现在重新启动计算机 3、reboot&#xff1a;现在重新启动计算机 4、su -&#xff1a;切换用户&#xff1b;passwd&#xff1a;修改用户密码 5、logou…

ChatGLM2-6B在Windows下的微调

ChatGLM2-6B在Windows下的微调 零、重要参考资料 1、ChatGLM2-6B! 我跑通啦&#xff01;本地部署微调&#xff08;windows系统&#xff09;&#xff1a;这是最关键的一篇文章&#xff0c;提供了Windows下的脚本 2、LangChain ChatGLM2-6B 搭建个人专属知识库&#xff1a;提供…

计算机网络—TCP

这里写目录标题 TCP头格式有哪些为什么需要TCP&#xff0c;TCP工作在哪什么是TCP什么是TCP连接如何确定一个TCP连接TCP和UDP的区别&#xff0c;以及场景TCP和UDP能共用一个端口&#xff1f;TCP的建立TCP三次握手过程为什么是三次握手、不是两次、四次why每次建立连接&#xff0…

2023年游戏买量能怎么玩?

疫情过后&#xff0c;一地鸡毛。游戏行业的日子也不好过。来看看移动游戏收入&#xff1a;2022年&#xff0c;移动游戏收入达到920亿美元&#xff0c;同比下降6.4%。这告诉我们&#xff0c;2022年对移动游戏市场来说是一个小挫折。 但不管是下挫还是上升&#xff0c;移动游戏市…

python技术栈 之 单元测试中mock的使用

一、什么是mock&#xff1f; mock测试就是在测试过程中&#xff0c;对于某些不容易构造或者不容易获取的对象&#xff0c;用一个虚拟的对象来创建以便测试的测试方法。 二、mock的作用 特别是开发过程中上下游未完成的工序导致当前无法测试&#xff0c;需要虚拟某些特定对象…

机器学习深度学习——RNN的从零开始实现与简洁实现

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——循环神经网络RNN &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文章对你们有所帮…

React实现关键字高亮

先看效果&#xff1a; 实现很简单通过以下这个函数&#xff1a; highLight (text, keyword ) > {return text.split(keyword).flatMap(str > [<span style{{ color: red, fontWeight: bold }}>{keyword}</span>, str]).slice(1);}展示某段文本时调用该函数…

完成图像反差处理

bmp图像的前54字节为图像头&#xff0c;第19个字节开始4字节为图像宽&#xff0c;第23字节开始4字节为图像高&#xff0c;图像大小为&#xff1a;972*720*3542099574&#xff0c;为宽*高*像素点头&#xff0c;如下&#xff1a; 图像的反差处理

Android系统-ServiceManager2

目录 引言&#xff1a; 获取ServiceManager 流程图 注册系统服务 获取系统服务 引言&#xff1a; 注册或使用服务之前&#xff0c;需要通过ServiceManager这个DNS来找到对应的服务。那怎么找到ServiceManager呢&#xff1f; 怎么注册系统服务&#xff1f; 怎么获取系统…

Golang 函数定义及使用

文章目录 一、函数定义格式二、函数定义及使用 一、函数定义格式 //func: 函数定义关键字 //function_name&#xff1a;函数名称 //parameter_List: 函数参数列表&#xff0c;多个时使用逗号拆分 //return_types&#xff1a;函数返回类型&#xff0c;返回多个值时使用逗号拆分…

SpringBoot 2.1.7.RELEASE + Activiti 5.18.0 喂饭级练习手册

环境准备 win10 eclipse 2023-03 eclipse Activiti插件 Mysql 5.x Activiti的作用等不再赘叙&#xff0c;直接上代码和细节 POM <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId>…

web前端之CSS操作

文章目录 一、CSS操作1.1 html元素的style属性1.2 元素节点的style属性1.3 cssText属性 二、事件2.1 事件处理程序2.1.1 html事件2.1.2 DOM0事件&#xff08;适合单个事件&#xff09;2.1.3 DOM2事件&#xff08;适合多个事件&#xff09; 2.2 事件之鼠标事件2.3 事件之Event事…

Python分享之 Spider

一、网络爬虫 网络爬虫又被称为网络蜘蛛&#xff0c;我们可以把互联网想象成一个蜘蛛网&#xff0c;每一个网站都是一个节点&#xff0c;我们可以使用一只蜘蛛去各个网页抓取我们想要的资源。举一个最简单的例子&#xff0c;你在百度和谷歌中输入‘Python&#xff0c;会有大量和…

选择最适合自己的笔记本

选择最适合自己的笔记本电脑 一、了解笔记本品牌一线品牌准一线品牌二线品牌三线品牌 二、笔记本入手渠道笔记本入手渠道 三、根据需求选择机型使用需求1.日常使用2.商务办公、财务3.轻度剪辑、ps4.代码5.创意设计6.游戏 四、笔记本电脑配置如何选1.cpu2.显卡&#xff08;GPU&a…