【备战秋招】每日一题:5月13日美团春招第三题:题面+题目思路 + C++/python/js/Go/java带注释

news/2024/5/20 0:50:38/文章来源:https://blog.csdn.net/m0_73659489/article/details/131222928

为了更好的阅读体检,为了更好的阅读体检,,可以查看我的算法学习博客第三题-火车调度

在线评测链接:P1288

题目描述

塔子哥是一位火车车厢调度员。

这一天,一列带有 n 个编号车厢的列车进站了,编号为 1\rightarrow n 。但是,这些车厢的编号并不是按从左到右递增的顺序,为了后面的工作方便展开,塔子哥想把火车调整成从左到右递增的顺序,即 [1,2,3,...,n] ,但他只能进行一种操作:首先他要在火车中任意选择两个车厢取出。然后他将两个车厢中较大的放在火车的最右边,较小的放在火车的最左边。

他可以进行无限次这样的操作,他想知道最少需要多少次才能将火车调整为从左到右递增的顺序。

输入描述

第一行是数组的长度: n . 第二行有n个数字p_i (i=1,2,3,...,n)表示从左到右的车厢编号。( 1\leq n\leq 50000,1\leq p_i\leq n)

输出描述

输出一个整数,表示最少需要操作多少次。

样例

输入

7
1 3 5 2 4 6 7

输出

3

说明

第一步选择5,3,第二步选2,6,第三步选1,7。

思路

思维,构造

考虑什么数需要更新位置?

先来考虑 n 为偶数的情况:mid = n/2

记 pos[x] 为数 x 在数组中的位置

将数分为 [1,mid] 和 [mid+1,n] 两部分

  • 对于 [1,mid] 这部分数:找到一个最大的 j,满足存在 j\in[1,mid],k\in[1,mid],j<k,pos[j]>pos[k],那么 [1,j] 这 j 个数都要更新位置,故这部分需要更新 j 次。

  • 对于 [mid+1,n] 这部分数,找到一个最小的 j ,满足存在 j\in [mid+1,n],k\in[mid+1,n],j>k,pos[j]<pos[k],那么 [j+1,n] 这 n-j 个数都要更新位置,故这部分需要更新 n-j 次。

  • 两者取 \max,即\max(j,n-j) 为答案。

对于 n 为奇数的情况,其实就是多了一个中间的数 (n+1)/2。本质没有区别。

时间复杂度:O(n)

类似题目推荐

一开始塔子哥就感觉到这道题目非常的CodeForces风,力扣上没有类似的思维题。后来于某天233大佬成功破案,这就是一道codeforces的原题:CF-1792C

Codefun2000

P1264. 塔子月赛1-第三题-2333的小清新数论题

代码

CPP

#include <bits/stdc++.h>
using namespace std;
​
int main()
{int n;cin >> n;vector<int> a(n);for (int i = 0; i < n; ++i) cin >> a[i];
​int ans = 0;if (n & 1) {// 奇数情况int L = (n + 1) / 2, R = L;for (int i = 0; i < n; ++i) {if (a[i] == L) {// 找到从 L 开始往前递减 1 可以到的最小数 t,从 t 到 L 均不需要更新位置,而从 1 到 t - 1 这些数需要更新位置int t = L;for (int j = i; j >= 0; --j) {if (a[j] == t) t -= 1;}ans = max(ans, t);
​// 找到从 R 开始往后递增 1 可以到的最大数 t,从 R 到 t 均不需要更新位置,而从 t + 1 到 n 这些数需要更新位置t = R;for (int j = i; j < n; ++j) {if (a[j] == t) t += 1;}ans = max(ans, n - t + 1);}}// 奇数情况下,L 和 R 的位置相同,故无需单独考虑 L 的位置在 R 的位置之后这种情况} else {// 偶数情况int L = n / 2, R = L + 1;int pL = -1, pR = -1;for (int i = 0; i < n; ++i) {if (a[i] == L) {pL = i;// 找到从 L 开始往前递减 1 可以到的最小数 t,从 t 到 L 均不需要更新位置,而从 1 到 t - 1 这些数需要更新位置int t = L;for (int j = i; j >= 0; --j) {if (a[j] == t) t -= 1;}ans = max(ans, t);}
​if (a[i] == R) {pR = i;// 找到从 R 开始往后递增 1 可以到的最大数 t,从 R 到 t 均不需要更新位置,而从 t + 1 到 n 这些数需要更新位置int t = R;for (int j = i; j < n; ++j) {if (a[j] == t) t += 1;}ans = max(ans, n - t + 1);}}// 如果 L 的位置在 R 的后面,则所有的数都要更新位置if (pL > pR) {ans = n / 2;}}
​cout << ans << "\n";
​return 0;
}

python

n = int(input())
a = list(map(int, input().split()))
​
ans = 0
if n % 2 == 1:# 奇数情况L = (n + 1) // 2R = Lfor i in range(n):if a[i] == L:# 找到从 L 开始往前递减 1 可以到的最小数 t,从 t 到 L 均不需要更新位置,而从 1 到 t - 1 这些数需要更新位置t = Lfor j in range(i, -1, -1):if a[j] == t:t -= 1ans = max(ans, t)
​# 找到从 R 开始往后递增 1 可以到的最大数 t,从 R 到 t 均不需要更新位置,而从 t + 1 到 n 这些数需要更新位置t = Rfor j in range(i, n):if a[j] == t:t += 1ans = max(ans, n - t + 1)
else:# 偶数情况L = n // 2R = L + 1pL = -1pR = -1for i in range(n):if a[i] == L:pL = i# 找到从 L 开始往前递减 1 可以到的最小数 t,从 t 到 L 均不需要更新位置,而从 1 到 t - 1 这些数需要更新位置t = Lfor j in range(i, -1, -1):if a[j] == t:t -= 1ans = max(ans, t)
​if a[i] == R:pR = i# 找到从 R 开始往后递增 1 可以到的最大数 t,从 R 到 t 均不需要更新位置,而从 t + 1 到 n 这些数需要更新位置t = Rfor j in range(i, n):if a[j] == t:t += 1ans = max(ans, n - t + 1)
​# 如果 L 的位置在 R 的后面,则所有的数都要更新位置if pL > pR:ans = n // 2
​
print(ans)

Java

import java.util.*;
​
public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();int[] a = new int[n];for (int i = 0; i < n; ++i) {a[i] = sc.nextInt();}
​int ans = 0;if (n % 2 == 1) {// 奇数情况int L = (n + 1) / 2;int R = L;for (int i = 0; i < n; ++i) {if (a[i] == L) {// 找到从 L 开始往前递减 1 可以到的最小数 t,从 t 到 L 均不需要更新位置,而从 1 到 t - 1 这些数需要更新位置int t = L;for (int j = i; j >= 0; --j) {if (a[j] == t) {t -= 1;}}ans = Math.max(ans, t);
​// 找到从 R 开始往后递增 1 可以到的最大数 t,从 R 到 t 均不需要更新位置,而从 t + 1 到 n 这些数需要更新位置t = R;for (int j = i; j < n; ++j) {if (a[j] == t) {t += 1;}}ans = Math.max(ans, n - t + 1);}}// 奇数情况下,L 和 R 的位置相同,故无需单独考虑 L 的位置在 R 的位置之后这种情况} else {// 偶数情况int L = n / 2;int R = L + 1;int pL = -1;int pR = -1;for (int i = 0; i < n; ++i) {if (a[i] == L) {pL = i;// 找到从 L 开始往前递减 1 可以到的最小数 t,从 t 到 L 均不需要更新位置,而从 1 到 t - 1 这些数需要更新位置int t = L;for (int j = i; j >= 0; --j) {if (a[j] == t) {t -= 1;}}ans = Math.max(ans, t);}
​if (a[i] == R) {pR = i;// 找到从 R 开始往后递增 1 可以到的最大数 t,从 R 到 t 均不需要更新位置,而从 t + 1 到 n 这些数需要更新位置int t = R;for (int j = i; j < n; ++j) {if (a[j] == t) {t += 1;}}ans = Math.max(ans, n - t + 1);}}// 如果 L 的位置在 R 的后面,则所有的数都要更新位置if (pL > pR) {ans = n / 2;}}
​System.out.println(ans);}
}

Go

package main
​
import "fmt"
​
func main() {var n intfmt.Scan(&n)a := make([]int, n)for i := 0; i < n; i++ {fmt.Scan(&a[i])}
​ans := 0if n%2 == 1 {// 奇数情况L, R := (n+1)/2, (n+1)/2for i := 0; i < n; i++ {if a[i] == L {// 找到从 L 开始往前递减 1 可以到的最小数 t,从 t 到 L 均不需要更新位置,而从 1 到 t - 1 这些数需要更新位置t := Lfor j := i; j >= 0; j-- {if a[j] == t {t -= 1}}ans = max(ans, t)
​// 找到从 R 开始往后递增 1 可以到的最大数 t,从 R 到 t 均不需要更新位置,而从 t + 1 到 n 这些数需要更新位置t = Rfor j := i; j < n; j++ {if a[j] == t {t += 1}}ans = max(ans, n-t+1)}}// 奇数情况下,L 和 R 的位置相同,故无需单独考虑 L 的位置在 R 的位置之后这种情况} else {// 偶数情况L, R := n/2, n/2+1pL, pR := -1, -1for i := 0; i < n; i++ {if a[i] == L {pL = i// 找到从 L 开始往前递减 1 可以到的最小数 t,从 t 到 L 均不需要更新位置,而从 1 到 t - 1 这些数需要更新位置t := Lfor j := i; j >= 0; j-- {if a[j] == t {t -= 1}}ans = max(ans, t)}
​if a[i] == R {pR = i// 找到从 R 开始往后递增 1 可以到的最大数 t,从 R 到 t 均不需要更新位置,而从 t + 1 到 n 这些数需要更新位置t := Rfor j := i; j < n; j++ {if a[j] == t {t += 1}}ans = max(ans, n-t+1)}}// 如果 L 的位置在 R 的后面,则所有的数都要更新位置if pL > pR {ans = n / 2}}
​fmt.Println(ans)
}
​
func max(x, y int) int {if x > y {return x}return y
}

Js

process.stdin.resume();
process.stdin.setEncoding('utf-8');
let input = '';
process.stdin.on('data', (data) => {input += data;
});
process.stdin.on('end', () => {const lines = input.trim().split('\n');const n = parseInt(lines[0]);const a = lines[1].split(' ').map(x => parseInt(x));
​let ans = 0;if (n % 2 === 1) {// 奇数情况const L = Math.floor((n + 1) / 2), R = L;for (let i = 0; i < n; ++i) {if (a[i] === L) {// 找到从 L 开始往前递减 1 可以到的最小数 t,从 t 到 L 均不需要更新位置,而从 1 到 t - 1 这些数需要更新位置let t = L;for (let j = i; j >= 0; --j) {if (a[j] === t) t -= 1;}ans = Math.max(ans, t);
​// 找到从 R 开始往后递增 1 可以到的最大数 t,从 R 到 t 均不需要更新位置,而从 t + 1 到 n 这些数需要更新位置t = R;for (let j = i; j < n; ++j) {if (a[j] === t) t += 1;}ans = Math.max(ans, n - t + 1);}}// 奇数情况下,L 和 R 的位置相同,故无需单独考虑 L 的位置在 R 的位置之后这种情况} else {// 偶数情况const L = Math.floor(n / 2), R = L + 1;let pL = -1, pR = -1;for (let i = 0; i < n; ++i) {if (a[i] === L) {pL = i;// 找到从 L 开始往前递减 1 可以到的最小数 t,从 t 到 L 均不需要更新位置,而从 1 到 t - 1 这些数需要更新位置let t = L;for (let j = i; j >= 0; --j) {if (a[j] === t) t -= 1;}ans = Math.max(ans, t);}
​if (a[i] === R) {pR = i;// 找到从 R 开始往后递增 1 可以到的最大数 t,从 R 到 t 均不需要更新位置,而从 t + 1 到 n 这些数需要更新位置let t = R;for (let j = i; j < n; ++j) {if (a[j] === t) t += 1;}ans = Math.max(ans, n - t + 1);}}// 如果 L 的位置在 R 的后面,则所有的数都要更新位置if (pL > pR) {ans = Math.floor(n / 2);}}
​console.log(ans);
});

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

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

相关文章

kafka 报错 - Cannot assign requested address

背景 在华为云服务器上跑了 zookeeper 和 kafka 的 broker&#xff0c;想内外网分流&#xff0c;重点就是做不到从外网去消费&#xff0c;比如用自己的 windows 笔记本去消费。 配置 server.properties 的 listener 为 broker 所在机子的的内网 IP 后&#xff0c;终于能 star…

ECC算法学习(一)算法公式

ECC 一、ECC简介优缺点运用 二、算法理论基础1. 椭圆曲线的加法2. 椭圆曲线的二倍运算3. 同余运算4. 有限域5. 乘法逆元 三、算法公式1、有限域的负元2、有限域的加法&#xff0c; P Q P Q PQ3. 斜率计算&#xff08;PQ即要计算P点切线&#xff0c;需要求导&#xff09;4. 椭…

【位图布隆过滤器海量数据面试题】

文章目录 1 位图2 布隆过滤器 1 位图 首先我们来看看一个腾讯的面试题&#xff1a;给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数中。 分析&#xff1a; 40亿个不重复整形数据&#xff0c;大概有160亿字节…

Axios和Spring MVC[前端和后端的请求和响应处理]

在前后端交互中&#xff0c;Axios和Spring MVC扮演着不同的角色&#xff0c;分别负责前端和后端的请求和响应处理。它们之间的作用如下&#xff1a; Axios&#xff08;前端&#xff09;&#xff1a; 发送HTTP请求&#xff1a;前端使用Axios库发送HTTP请求到后端。可以使用Axi…

机器学习实践(1.1)XGBoost分类任务

前言 XGBoost属于Boosting集成学习模型&#xff0c;由华盛顿大学陈天齐博士提出&#xff0c;因在机器学习挑战赛中大放异彩而被业界所熟知。相比越来越流行的深度神经网络&#xff0c;XGBoost能更好的处理表格数据&#xff0c;并具有更强的可解释性&#xff0c;还具有易于调参…

hard fault on thread: mqtt0解决办法

rt thread版本4.1.0 使用paho mqtt软件包 运行一段时间后出现 psr: 0x21000000 r00: 0x5036fc8f r01: 0x5036fc88 r02: 0x00000000 r03: 0x5036fc8f r04: 0x00000007 r05: 0x00000063 r06: 0x00005f70 r07: 0x2001f1d8 r08: 0xdeadbeef r09: 0xdeadbeef r10: 0xdeadbeef r11…

关于Java SSM框架的面试题

一、Spring面试题 1、Spring 在ssm中起什么作用&#xff1f; Spring&#xff1a;轻量级框架作用&#xff1a;Bean工厂&#xff0c;用来管理Bean的生命周期和框架集成。两大核心&#xff1a;1、IOC/DI(控制反转/依赖注入) &#xff1a;把dao依赖注入到service层&#xff0c;se…

28.vite

目录 1 一些概念 1.1 单页面应用程序SPA 1.2 vite 2 初始化vite项目 3 项目中的文件 1 一些概念 1.1 单页面应用程序SPA 单页面应用程序是只有一个页面的前端&#xff0c;切换页面通过前端路由来切换 特点如下 实现了前后端分离&#xff0c;后端仅出接口&#…

动态规划III (买股票-121、122、123、188、309)

CP121 买股票的最佳时机 题目描述&#xff1a; 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利…

YOLOv5-7.0添加解耦头

Decoupled Head Decoupled Head是由YOLOX提出的用来替代YOLO Head&#xff0c;可以用来提升目标检测的精度。那么为什么解耦头可以提升检测效果呢&#xff1f; 在阅读YOLOX论文时&#xff0c;找到了两篇引用的论文&#xff0c;并加以阅读。 第一篇文献是Song等人在CVPR2020发表…

【59天|503.下一个更大元素II ● 42. 接雨水】

503.下一个更大元素II class Solution { public:vector<int> nextGreaterElements(vector<int>& nums) {stack<int> st;int n nums.size();vector<int> res (n, -1);for(int i0; i<2*n;i){while(!st.empty()&&nums[i%n]>nums[st.t…

随机的乐趣和游戏

1、猜数字游戏 #GuessingGame.py import random the_number random.randint(1, 10) print("计算机已经在1到10之间随机生成了一个数字&#xff0c;") guess int(input("请你猜猜是哪一个数字: ")) while guess ! the_number:if guess > the_number:p…

PHP设计模式21-工厂模式的讲解及应用

文章目录 前言基础知识简单工厂模式工厂方法模式抽象工厂模式 详解工厂模式普通的实现更加优雅的实现 总结 前言 本文已收录于PHP全栈系列专栏&#xff1a;PHP快速入门与实战 学会好设计模式&#xff0c;能够对我们的技术水平得到非常大的提升。同时也会让我们的代码写的非常…

淘宝详情页分发推荐算法总结:用户即时兴趣强化

转子&#xff1a;https://juejin.cn/post/6992169847207493639 商品详情页是手淘内流量最大的模块之一&#xff0c;它加载了数十亿级商品的详细信息&#xff0c;是用户整个决策过程必不可少的一环。这个区块不仅要承接用户对当前商品充分感知的诉求&#xff0c;同时也要能肩负起…

Spark大数据处理学习笔记1.5 掌握Scala内建控制结构

文章目录 一、学习目标二、条件表达式&#xff08;一&#xff09;语法格式&#xff08;二&#xff09;执行情况&#xff08;三&#xff09;案例演示任务1、根据输入值的不同进行判断任务2、编写Scala程序&#xff0c;判断奇偶性 三、块表达式&#xff08;一&#xff09;语法格式…

Redis入门 - Lua脚本

原文首更地址&#xff0c;阅读效果更佳&#xff01; Redis入门 - Lua脚本 | CoderMast编程桅杆https://www.codermast.com/database/redis/redis-scription.html Redis 脚本使用 Lua 解释器来执行脚本。 Redis 2.6 版本通过内嵌支持 Lua 环境。执行脚本的常用命令为 EVAL。 …

不要把异常当做业务逻辑,这性能可能你无法承受

一&#xff1a;背景 1. 讲故事 在项目中摸爬滚打几年&#xff0c;应该或多或少的见过有人把异常当做业务逻辑处理的情况(┬&#xff3f;┬)&#xff0c;比如说判断一个数字是否为整数,就想当然的用try catch包起来&#xff0c;再进行 int.Parse&#xff0c;如果抛异常就说明不…

Unity入门8——音效系统

一、音频文件参数面板 Force To Mono&#xff1a;多声道转单声道 Normalize&#xff1a;强制为单声道时&#xff0c;混合过程中被标准化 Load In Background&#xff1a;后台加载&#xff0c;不阻塞主线程&#xff0c;适合大音效 Ambisonic&#xff1a;立体混响声 非常适合 36…

JUC并发编程初学

什么是JUC进程和线程回顾Lock锁生产者和消费者8锁的线程集合类不安全CallableCountDownLatch、CyclicBarrier、Semaphore读写锁阻塞队列线程池四大函数式接口Stream流式计算分支合并异步回调JMMvolatile深入单例模式深入理解CAS原子引用可重入锁、公平锁非公平锁、自旋锁、死锁…

使用单元测试框架unittest进行有效测试

一、介绍 在软件开发中&#xff0c;单元测试是一种测试方法&#xff0c;它用于检查单个软件组件&#xff08;例如函数或方法&#xff09;的正确性。Python 提供了一个内置的单元测试库&#xff0c;名为 unittest&#xff0c;可以用来编写测试代码&#xff0c;然后运行测试&…