大厂真题:【模拟】阿里蚂蚁2023秋招-讨厌鬼的区间

题目描述与示例

题目描述

讨厌鬼有一个数x,他每次操作可以令x = x + 1或x = x - 1

讨厌鬼还有两个区间[l1, r1]和[l2, r2],讨厌鬼想知道,令x同时满足以下条件的最小操作数是多少?

  1. l1 ≤ x ≤ r1,且x是2的倍数
  2. l2 ≤ x ≤ r2,且x是3的倍数
    请输出这个操作数

输入描述

一行输入五个整数x, l1, r1, l2, r2

1 ≤ x ≤ 10^12

1 ≤ l1 ≤ r1 ≤ 10^12

1 ≤ l2 ≤ r2 ≤ 10^12

输出描述

一行一个整数,表示最小操作数。若不存在这样的操作,输出-1。

示例一

输入

5 4 6 1 9

输出

1

说明

+1把5变成6,满足2个条件

示例二

输入

2 2 4 2 8

输出

-1

时空限制

时间限制: C/C++ 1000MS,其他语言 2000MS

内存限制: C/C++ 256M,其他语言 512M

解题思路

条件转换

数据范围很大,考虑O(1)复杂度的算法。

经过若干次操作之后,x需要同时落在区间[l1, r1]和[l2, r2]中,令l = max(l1, l2),r = min(r1, r2),该条件转化为x最终需要落入区间[l, r]中。

x还需要同时是2和3的倍数,由于2和3互质,故该条件转化为x最终需要是6的倍数。

因此题目可以转化为,在区间[l, r]中找到一个距离x最近的一个6的倍数,这个数和x的差的绝对值就是所求的最小操作数。

分类讨论

在区间[l, r]中找到一个距离x最近的一个6的倍数,一共存在3种情况

  1. x在区间[l, r]左边,即x < l
  2. x在区间[l, r]右边,即x > r
  3. x在区间[l, r]之间,即l <= x <= r

对于情况一,我们需要找到大于等于l的第一个6的倍数a,可以用如下方式得到

a = l + ((6 - l % 6) % 6)

对于情况二,我们需要找到小于等于r的第一个6的倍数b,可以用如下方式得到

b = r - r % 6

  • 如果存在a > b,说明区间[l, r]实际上并不包含任何6的倍数,返回-1
  • 如果是第一种情况,x落在l的左边,那么a是[l, r]中距离x最近的6的倍数,返回a-x
  • 如果是第二种情况,x落在r的右边,那么b是[l, r]中距离x最近的6的倍数,返回x-b
    if a > b:
    return -1
    elif x < l:
    return a-x
    elif x > r:
    return x-b

对于情况三,我们需要找到第一个小于等于x的6的倍数xa以及第一个大于等于x的6的倍数xb。可以用类似于求a和b的方法求得。即

xa = x - x % 6

xb = x + ((6 - x % 6) % 6)

对于xa和xb,也要分别讨论与l和r之间的大小关系,查询xa和xb是否落在区间[l, r]中。

  • 如果xa落在l的左边,则xb是距离x最近的6的倍数,返回xb-x
  • 如果xb落在r的右边,则xa是距离x最近的6的倍数,返回x-xa
  • 如果xa和xb均落在[l,r]中,那么选距离更近的作为答案,返回min(x-xa, xb-x)
    if xa < l:
    return xb-x
    elif xb > r:
    return x-xa
    else:
    return min(x-xa, xb-x)

代码

Python

题目:【模拟】阿里蚂蚁2023秋招-讨厌鬼的区间

作者:闭着眼睛学数理化

算法:模拟/数学

代码有看不懂的地方请直接在群上提问

def help(x, l, r):

a是大于等于l的第一个6的倍数

a = l + ((6 - l % 6) % 6)

b是小于等于r的第一个6的倍数

b = r - r % 6

# 如果a大于b,说明区间中不包含6的倍数,返回-1
if a > b:
    return -1
# 以下条件语句中,区间[l, r]中一定包含6的倍数
# 第一种情况,x落在l左边,a是答案
elif x < l:
    return a-x
# 第二种情况,x落在r的右边,b是答案
elif x > r:
    return x-b
# 第三种情况,x落在区间[l,r]之间
else:
    # 需要计算,比x小的第一个6的倍数xa和比x大的第一个6的倍数xb
    xa = x - x % 6
    xb = x + ((6 - x % 6) % 6)
    # 如果xa落在l的左边,则xb是距离x最近的6的倍数
    if xa < l:
        return xb-x
    # 如果xb落在r的右边,则xa是距离x最近的6的倍数
    elif xb > r:
        return x-xa
    else:
    # 如果xa和xb均落在[l,r]中,那么选距离更近的作为答案
        return min(x-xa, xb-x)

输入5个参数

x, l1, r1, l2, r2 = map(int, input().split())

分别获得l和r

l = max(l1, l2)

r = min(r1, r2)

如果r小于l,那么区间不存在,直接输出-1

if r < l:

print(-1)

否则则调用help计算结果

else:

ans = help(x, l, r)

print(ans)

Java

C++

时空复杂度

时间复杂度:O(1)。

空间复杂度:O(1)。

华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接 OD算法冲刺训练课程表 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1336了解更多

相关推荐
AI街潜水的八角5 分钟前
基于C++的决策树C4.5机器学习算法(不调包)
c++·算法·决策树·机器学习
白榆maple30 分钟前
(蓝桥杯C/C++)——基础算法(下)
算法
JSU_曾是此间年少35 分钟前
数据结构——线性表与链表
数据结构·c++·算法
此生只爱蛋1 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法
咕咕吖2 小时前
对称二叉树(力扣101)
算法·leetcode·职场和发展
九圣残炎3 小时前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode
lulu_gh_yu3 小时前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
丫头,冲鸭!!!3 小时前
B树(B-Tree)和B+树(B+ Tree)
笔记·算法
Re.不晚3 小时前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
为什么这亚子4 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算