秋招突击——笔试整理——蚂蚁集团笔试整理

news2024/9/22 19:27:41

文章目录

    • 引言
    • 正文
      • 第一题——算折扣
        • 个人实现
      • 第二题
        • 个人实现
          • 错误实现一
          • 修改实现二
      • 第三题
        • 个人实现
    • 总结

引言

  • 今天做了蚂蚁集团的笔试,踩了很多雷,这里整理一下,记录一下,防止下次再踩雷!

正文

第一题——算折扣

题目

  • 小苯看中了一件价值为p元的物品,他手里有1个“打折券"和 1个“立减券”。两种优惠券可以都用在物品上,且使用顺序也是任意的。

  • 两种优惠券分别以整数x和y的方式给出。

    • 打折券:如果当前物品价格为p,使用后,物品价格变为z* p/100上取整
    • 立减券:如果当前物品价格为P,使用后,物品价格变为max(0,p-y)。即物品价格立减y元,但最多减到 0。
  • 小苯想知道,这件价值为 p的物品最少可以花多少钱买到。

个人实现
  • 这个题就是计算一下两种情况的具体价格,然后比大小就行了,是一个签到题,但是卡了一下!int类型整除,后面那个数字忘记加个".0",最后报错了!
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()){
            double p = sc.nextDouble();
            double x = sc.nextDouble();
            double y = sc.nextDouble();
            int cost_1 = (int)Math.ceil(x * p / 100 - y);
            int cost_2 = (int)Math.ceil((x - y) * p / 100);

            System.out.println(Math.min(cost_1, cost_2));

        }
    }
}

总结

  • 对于Java中的整除而言,如果两边的数据不一致会出现自动类型转换,顺序如下
    • byte < short < int < long < float < double
  • 这里不要忘记了

第二题

题目

  • 小红拿到了一个数组,她可以进行最多一次操作:

    • 选择一个元素,使其加1。小红希望操作结束后,数组所有元素乘积的未尾有尽可能多的0。你能帮帮她吗?
  • 输入描述

    • 第一行输入一个正整数n,代表数组的大小
      • n在【1, 1 0 5 10^5 105
    • 第二行输入n个正整数ai,代表数组的元素
      • ai在【1, 1 0 9 10^9 109
  • 输出描述

    • 一个整数,标识末尾零的个数
个人实现
错误实现一

这个我直接模拟了,想着就算会越界,也会过一部分样例,然后报一个执行异常啥的,结果一个样例没过,直接报错!

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()){
           int n = sc.nextInt();
           int[] nums = new int[n];
           long mulAll = 1;
           for(int i  = 0; i < n; i++) {
               nums[i] = sc.nextInt();
               mulAll *= nums[i];
           }
           
           int res = 0;
           for(int i = 0 ;i < n;i ++){
               int curNum = nums[i] + 1;
               long curMul = mulAll / nums[i] * curNum;
               int count = 0;
               while(curMul % 10 == 0){
                   count ++;
                   curMul /= 10;
               }
               
               res = Math.max(res, count);
                
           }
            System.out.println(res);
        }
    }
}
  • 这样是能够过测试样例,但是一交上去,一个样例都没通过,而且会显示答案错误
  • 错误原因分析如下
    • int类型的范围【 10 − 10 {10}^{-10} 1010, 10 10 {10}^{10} 1010
    • long类型的范围【 10 − 19 {10}^{-19} 1019, 10 19 {10}^{19} 1019
    • 数字最多有 1 0 5 10^5 105个,也就是9的 1 0 5 10^5 105次方,啥玩意都得越界,根本不可能使用这种方法实现
  • 下述是越界之后的运行情况:不会报错,不要搞错了!

在这里插入图片描述
这些东西还是在做题的时候意识到了,然后测试了一下,发现没有报错,才知道的,浪费了多少时间!!

修改实现二

思路分析

  • 10 = 2 *5
  • a * b * c,相当于a1 * a2 * a3 * b1 * b2 * b3 * c1 * c2 * c3 ,其中a1 * a2 * a3 = a,b1 * b2 * b3 = b,c1 * c2 * c3 = c
  • 这里是若干数相乘,判定最后还剩下几个零,就是看能够拆成几个2和几个5,然后取一个最小值
import java.util.*;

public class Main {


    static int[] count2And5(int num) {
        int[] res = {0, 0};
        if (num % 2 == 0) {
            int curNum = num;
            while (curNum % 2 == 0) {
                res[0]++;
                curNum /= 2;
            }
        }
        if (num % 5 == 0) {
            int curNum = num;
            while (curNum % 5 == 0) {
                res[1]++;
                curNum /= 5;
            }
        }
        return res;
    }


    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int n = in.nextInt();
            int[] nums = new int[n];
            Map<Integer, Integer> map2 = new HashMap<>();
            Map<Integer, Integer> map5 = new HashMap<>();

            // 计算所有的整数中的2的数量和5的数量
            int count2 = 0;
            int count5 = 0;
            for (int i = 0; i < n; i++) {
                nums[i] = in.nextInt();
                if (map2.containsKey(nums[i]) || map5.containsKey(nums[i])) {
                    count2 += map2.getOrDefault(nums[i], 0);
                    count5 += map5.getOrDefault(nums[i], 0);
                } else {
                    int[] countNum = count2And5(nums[i]);
                    count2 += countNum[0];
                    count5 += countNum[1];
                    map2.put(nums[i], countNum[0]);
                    map5.put(nums[i], countNum[1]);
                }
            }

            // 逐个遍历修改每一个数字
            int res = Math.min(count5, count2);
            for (int i = 0; i < n; i++) {
                // 计算出修改之后的2和5的数量
                int curNum = nums[i] + 1;
                int curCount2 = 0;
                int curCount5 = 0;
                if (map2.containsKey(curNum) || map5.containsKey(curNum)) {
                    curCount2 = map2.getOrDefault(curNum, 0);
                    curCount5 = map5.getOrDefault(curNum, 0);
                } else {
                    int[] countNum = count2And5(curNum);
                    curCount2 = countNum[0];
                    curCount5 = countNum[1];
                    map2.put(curNum, countNum[0]);
                    map5.put(curNum, countNum[1]);
                }

                // 计算修改之后的最大值
                int curNum2 = count2 - map2.get(nums[i]) + curCount2;
                int curNum5 = count5 - map5.get(nums[i]) + curCount5;
                res = Math.max(res,Math.min(curNum2,curNum5));
            }
            System.out.println(res);

        }
    }
}

在这里插入图片描述

  • 记得这样写的代码是全过的,没有问题!

总结

  • 数据类型的溢出,并不会报异常,什么问题都没有,会正常输出,然后给你一个答案错误!
  • 数据溢出会报答案错误!

第三题

题目内容

  • 小苯来到了一座山脉,山谷中有n座山,每座山都有一个高度h1。有些山之间有路径连接,例如如果a号山和b号山之间有路径,如果小苯想的话,他可以从a山走到b山,同样的,也可以从b山走到a山.
  • 但小苯很懒,如果两座山之间的高度差大于一定的值k,他就不会走这条路(无论是上山还是下山),形式化的即。 ∣ h a − h b ∣ > k |h_a - h_b| > k hahb>k的话,小苯便不会走这条路,
  • 现在他提出了q次询问,每次询问他都会给出一组(a,b,k),他想知道,如果他从a山出发,高度差大于k的路径他不走,能否找到一条路使得他能走到b山呢,请你帮帮他吧,

输入说明

  • 输入包含1+m+q行。
  • 第一行三个正整数
  • n{1≤n≤2 * 1 0 5 10^5 105),m(1≤min(n·(n-1)/2,2x 1 0 5 10^5 105),q(1≤g≤2x 1 0 5 10^5 105),分别表示山脉中山的个数 n,山脉中山与山之间的路径数量 m,小苯的询问次数 q。
  • 接下来一行输入 几个正整数 hi(1 ≤ hi≤ 1 0 5 10^5 105),表示每座山的高度。
  • 接下来 m 行,每行两个正整数 u,υ(1 ≤ u,u≤ n,u≠ v),表示u号山到v号山有路径连接。
  • 接下来q行,每行三个正整数
  • α, b,k (1 ≤ a,b≤ n,a≠b),(1≤k≤ 1 0 9 10^9 109),分别表示小苯每次询问给出的信息。

输出说明

  • 可以到达就输出YES,不能就输出NO

样例

5 6 5
3 4 3 6 5
1 2
1 3
2 4
3 4
3 5
4 5
1 4 1
1 4 2
1 4 3
3 4 2
1 5 1


# 输出
NO
YES
YES
YES
NO
个人实现

思路分析

  • 这个题目最后问的是否可达,并不是求什么具体的到达路径,所以我默认会使用BFS,层序遍历的速度是快于DFS的,然后再加上限定高度的条件。PS:DFS经过系统判定,会超时

因为是通过高度差来判定当前路径是否能够走,所以需要计算每条路径的高度差,具体见下图
在这里插入图片描述
保存每两个点之间所有路径中,高度差最大的那条路径的高度差,具体样例如下,以节点1到节点4为例子

在这里插入图片描述
对于测试样例具体执行结果如下

  • 1 4 1:1小于最小高度差,所以不能通过
  • 1 4 2:2等于最小高度差,所以能够通过
  • 1 4 3:3大于最小高度差,所以能够通过
  • 一次类推,14 4或者1 4 5都是可以通过的,所以能够计算出到达目标节点的最短
  • 所以能够计算出每一个节点最短的路径差就行了,只要计算了,就需要保存或者更新就行
    在这里插入图片描述

**我觉得可能是我的代码能力还不够,我觉得这个题目,每个一个小时整不出来,真的!正常只能写一个DFS或者BFS **

import javax.crypto.Cipher;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int n = sc.nextInt();  //山头的数量
            int m = sc.nextInt();  // 道路的数量
            int q = sc.nextInt();  // 询问的次数
            int[] h = new int[n + 1];  // 高度
            for (int i = 1; i <= n; i++) h[i] = sc.nextInt();

            // 创建对应的邻接矩阵
            int[][] grid = new int[n + 1][n + 1];
            for (int[] row : grid) Arrays.fill(row, -1);
            for (int i = 0; i < m; i++) {
                int a = sc.nextInt();
                int b = sc.nextInt();
                grid[a][b] = Math.abs(h[a] - h[b]);
                grid[b][a] = grid[a][b];
            }

            // 遍历询问次数
            int[][] minGrid = new int[n + 1][n + 1];
            for (int[] row : minGrid) Arrays.fill(row, Integer.MAX_VALUE);// 保存对应节点满足条件的最小高度差
            boolean[][] minStatus = new boolean[n + 1][n + 1];  // 是否已经确定完最短路径
            for (int i = 0; i < q; i++) {
                int start = sc.nextInt();
                int goal = sc.nextInt();
                int hLimit = sc.nextInt();


                // 判定是否已经是最小值,如果已经是最小值了,还是不行,直接跳过
                if (minStatus[start][goal]) {
                    if (minGrid[start][goal] > hLimit) {
                        System.out.println("NO");
                        continue;
                    } else {
                        System.out.println("YES");
                        continue;
                    }
                }

                // 通过层序遍历来更新minGrid,并进行判断
                Queue<int[]> que = new ArrayDeque<>();
                // 这里生命一个visted数组
                // 默认是-1,表示没有访问过,其他数值记录的是从某一个点出发到当前路径下做需要的最低的高度差
                int[] visited = new int[n + 1];
                Arrays.fill(visited, Integer.MAX_VALUE);
                // 每一个节点记录两个状态,第一个元素是当前节点位置,下一个是从起点到当前节点的最大的高度差
                que.offer(new int[]{start, 0});
                while (!que.isEmpty()) {
                    // 队列不为空
                    int[] curNode = que.poll();
                    // 遍历所有的邻接节点
                    for (int j = 1; j <= n; j++) {
                        if (grid[curNode[0]][j] != -1) {

                            // 每一个节点要保存一个当前路径下的最大的高度差,然后在所有可能的路径中,保存一个最小的高度差
                            int curLen = Math.max(curNode[1], grid[curNode[0]][j]);

                            // 判断下一个目标点是否已经是目标节点
                            if (j == goal) {
                                minStatus[start][goal] = true;
                                minGrid[start][goal] = Math.min(minGrid[start][goal], curLen);
                            } else {
                                // 处理相同节点的情况
                                if (visited[j] <= curLen) {
                                    continue;
                                } else {
                                    // 当前路径经过这个节点的最大的高度差,小于已经记录的值,说明是一条有效的路线
                                    visited[j] = curLen;
                                }

                                // 将当前节点加入到对应的队列中
                                que.offer(new int[]{j, curLen});
                            }
                        }
                    }

                }
                if (minStatus[start][goal] && minGrid[start][goal] > hLimit) {
                    System.out.println("NO");
                } else {
                    System.out.println("YES");
                }
            }

        }
    }
}

注意点

  • 感觉对于BFS而言,还是得使用一个visited数组记录哪些数据已经是访问过的,然后在遍历后续节点,进行访问

总结

  • 数据溢出无异常,仅仅一个答案错误
  • 小数整除后面加个零
  • 我觉得最后一题还是蛮难的,后续我都想了半天,还是蛮难的,图这一块还不是很熟悉!再加油!

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

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

相关文章

基于窄带物联网的矿车追踪定位系统(论文+源码+实物)

1.功能设计 鉴于智能物联网的大趋势&#xff0c;本次基于窄带物联网的矿车追踪定位系统应具备以下功能&#xff1a; &#xff08;1&#xff09;实现实时定位&#xff0c;真正实现矿车随时随地定位; &#xff08;2&#xff09;定位精度高&#xff0c;采用该系统可以实现矿车在…

ISSACSIM-docker安裝

ISSAC SIM安裝 SetUp必要库安装开发工具配置參考資料 SetUp docker login 需要设置密码&#xff0c;是属于 NGC 的密码&#xff08;和NVDIA 不是一个&#xff09;如下&#xff1a; 必要库安装 1&#xff1a; python-3.10 版本及相应库安装 python env 2&#xff1a;python…

3.3.1 Linux中断的使能与屏蔽

点击查看系列文章 》 Interrupt Pipeline系列文章大纲-CSDN博客 3.3.1 Linux中断的使能与屏蔽 3.3.1.1 中断使能与屏蔽的三重关卡 本章的主题是hard_local_irq_disable()&#xff0c;它是对中断的关闭操作。为了彻底搞清楚中断关闭的机制&#xff0c;这里先对Linux使能与屏蔽…

深入理解HTTP的doGet与doPost

深入理解HTTP的doGet与doPost 1、doGet方法2、doPost方法3、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Web开发中&#xff0c;HTTP的GET和POST请求通过Servlet的doGet和doPost方法实现&#xff0c;两者在处理方式和适用场景上有…

那些令人惊艳的产品细节

随着智能手机的普及和互联网的发展&#xff0c;互联网产品已经渐渐渗透到我们的生活当中。 小编打开手机数了一下&#xff0c;不下50个APP&#xff0c;五花八门&#xff0c;最基本的生活服务类的&#xff0c;娱乐类的&#xff0c;社交等等。大家都会面临的一个问题是&#xff…

矩阵分块乘法的证明

设A是一个的矩阵&#xff0c;B是一个的矩阵&#xff0c; &#xff0c; A和B的分块矩阵分别记为 和 &#xff0c; 证明. 证明&#xff1a;设 要证明&#xff0c;可以首先证AB和是同型矩阵&#xff0c;即证明是一个的矩阵&#xff0c;接着再证&#xff0c;可以把AB做一个与同样…

1.C语言(变量和常量)

一、变量和常量的概念 变量&#xff1a;可以变的量 常量&#xff1a;不可变的量 变量举例&#xff1a; 1.变量的分类 1.1 分为全局变量和局部变量 全局变量&#xff1a;大括号外定义的变量 局部变量&#xff1a;大括号内的变量 1.2注意&#xff1a; 注入在同一范围内&am…

MAC多版本Java环境变量切换

在Mac上切换不同版本的Java环境变量可以通过以下步骤进行&#xff1a; 1. 打开终端&#xff08;Terminal&#xff09;应用程序。 2. 使用vi或者nano等编辑器打开.zshrc文件。如果该文件不存在&#xff0c;可以创建一个新的文件。 3.使用命令查看当前电脑已安装的JAVA版本 /usr…

不改一行代码轻松玩转 Go 应用微服务治理

作者&#xff1a;赵源筱 Go 应用微服务治理简介 Go 语言具有简洁、高效、并发性强等特性&#xff0c;已经被广泛认为是构建微服务的理想选择之一。Go 语言作为构建 Kubernetes、Docker 的主要编程语言&#xff0c;目前不仅在云原生基础组件领域中被广泛使用&#xff0c;也逐渐…

深入浅出LangChain:从模型调用到Agents开发的全流程指南

2024最新LangChain全面解析:从基础组件到AI应用构建 LangChain、LangGraph、LangSmith:打造完整AI解决方案的利器 本文将对于LangChain的基本组件、用途、用法进行介绍。 LangChain、LangGraph以及LangSmith的组合&#xff0c;极大的简化了开发者构建AI应用、Agents、Tools的…

看新闻知补贴不用专门薅羊毛!让工作变舒服的5个黄金法则——早读(逆天打工人爬取热门微信文章解读)

你们都不看新闻吗&#xff1f; 引言Python 代码第一篇 洞见 让工作变舒服的5个黄金法则第二篇 故事之散户结尾 (发了3000亿以旧换新补贴&#xff0c;大家没有感觉到力度吗&#xff1f; 时间到今年年底&#xff0c;9月-12月是消费区&#xff0c;中间夹杂个双十一&#xff0c;现在…

[易聊]软件项目测试报告

一、项目背景 随着互联网发展&#xff0c;各种各样的软件&#xff0c;比如游戏、短视频、购物软件中都有好友聊天功能&#xff0c;这是一个可在浏览器中与好友进行实时聊天的网页程序。“ 易聊 ”相对于一般的聊天软件&#xff0c;可以让用户免安装、随时随地的通过浏览器网页…

页面内容---复制粘贴【收藏版】【H5 web端亲测有效】

js中的复制粘贴 . 页面内容—复制粘贴【收藏版】【H5 web端亲测有效】 navigator.clipboard.writeText(copyText) 是 Web API 中的一个方法&#xff0c;用于将指定的文本内容复制到用户的剪贴板。这个方法属于 Clipboard API&#xff0c;它使得网页能够读取和写入剪贴板的内容…

【笔记】数据结构笔记02

toc 前话 算法学习网站&#xff1a; itcharge 代码随想录 labuladong 参考严蔚敏数据结构 树与等价问题 typedef PTree MFSet;//查找算法int find_mfset(MFSet S,int i){if(i<1||i>S.n) return -1;//i不属于任一集合for(ji;S.nodes[j].parent>0;jnodes[j].paren…

用宝塔部署项目到阿里云服务器访问不到的问题

今天用宝塔部署项目到阿里云&#xff0c;开始前端部署到了80端口&#xff0c;能正常访问&#xff0c;后端部署到了8081&#xff0c;但是后端接口一直无响应&#xff0c;最后超时。 但是java正常运行 系统防火墙的状态正常&#xff0c;策略也是放行 阿里云安全组也已经配置了 …

【性能优化】:从理论中来到实践中去(三)

本文主要介绍真实代码实现 序言 根据前面两篇文章的梳理 【性能优化】&#xff1a;探索系统瓶颈的根源&#xff08;一&#xff09; 【性能优化】&#xff1a;设计模式与技术方案解析&#xff08;二&#xff09; 我们已经知道了自动化跑批系统的核心功能&#xff0c;今天就来真…

如何使用混合搜索实现更好的 LLM RAG 检索

通过结合密集嵌入和BM25构建高级本地LLM RAG管道 基本的检索增强生成&#xff08;RAG&#xff09;管道使用编码器模型在给定查询时搜索相似文档。 这也被称为语义搜索&#xff0c;因为编码器将文本转换为高维向量表示&#xff08;称为嵌入&#xff09;&#xff0c;在该表示中&…

【计算机组成原理】汇总五、中央处理器

五、中央处理器 文章目录 五、中央处理器1.CPU的功能与结构1.1CPU功能1.2运算器1.2.1基本结构1.2.2 ALU和寄存器的数据通路 1.3控制器1.3.1基本结构1.3.2控制器功能 1.4CPU的基本结构 2.指令执行过程2.1指令周期2.2指令周期流程2.3数据流2.4指令执行方案&#xff1a;如何安排多…

Type-C接口诱骗取电快充方案

Type-C XSP08Q 快充协议芯片是一种新型电源管理芯片&#xff0c;主要负责控制充电电流和电压等相关参数&#xff0c;从而实现快速充电功能。Type-C XSP08Q快充协议是在Type-C接口基础上&#xff0c;加入了XSP08Q协议芯片的支持&#xff0c;很大程度上提升了充电速度。 正常情况…

ConcurrentHashMap扩容原理 | 存储流程 | 源码探究

新人写手&#xff0c;代码菜鸡&#xff1b;笔下生涩&#xff0c;诚惶诚恐。 初试锋芒&#xff0c;尚显青涩&#xff1b;望君指点&#xff0c;愿受教诲。 本篇文章将从源码的层面&#xff0c;探讨ConcurrentHashMap的存储流程以及扩容原理 Java版本为JDK17&#xff0c;源代码可…