【笔试题汇总】蚂蚁笔试题题解 2025.3.9

前两题较为简单,都是模拟题,本次T3需要一些技巧

题目分析

有n个格子排成一排,小红有m种操作,第i种操作是将第 l i l_i li个格子到第 r i r_i ri个格子染成红色。小红希望选择尽可能少的操作数将所有格子染红。你能帮帮她吗?
输入描述
第一行输入两个正整数n,m,代表格子数量以及操作种类数。接下来的m行,每行输入两个正整数, l i l_i li r i r_i ri代表每次操作选择的区间。
1 ≤ n ≤ 1 0 9 1 ≤n ≤ 10^9 1n109
1 ≤ m < 1 0 5 , 1 < l i < r i < n 1≤m < 10^5 ,1<l_i<r_i<n 1m<105,1<li<ri<n
输出描述
如果无法染色,请输出-1。否则第一行输入一个正整数,代表操作次数:第二行输入k个正整数 p i p_i pi,代表选择了哪些操作。


解题思路

贪心策略:

  1. 按左端点排序:先将所有区间按 l i l_i li升序排序,保证我们按顺序选择染色操作。
  2. 贪心选择最远能覆盖的区间
    • 我们从 start = 1 开始,每次寻找能覆盖当前起点的区间,并选取能覆盖最远右端点的区间。
    • 记录选择的操作编号,并更新起点 start = r
    • 若某次寻找发现无法找到可用区间,则说明无法染色,输出 -1
    • start \geq n,则成功染色,输出所需的操作数量及编号。

代码解析

# 读取输入
n, m = map(int, input().split())  # 读取格子数量和操作数量

start = 1  # 当前要覆盖的起点
end = n  # 终点

intervals = []  # 存储所有操作的区间
for index in range(m):
    l, r = map(int, input().split())  # 读取操作区间
    intervals.append((l, r, index + 1))  # 记录区间和操作编号

intervals.sort()  # 按左端点升序排序

i = 0  # 遍历区间的索引
res = 0  # 记录选择的操作数量
find = False  # 是否成功覆盖整个区间
selected_operations = []  # 记录选择的操作编号

while i < m:
    r = -float('inf')  # 记录当前能覆盖的最远右端点
    best_op = -1  # 记录最优的操作编号

    # 选择能够覆盖 `start` 的所有区间中最远的一个
    while i < m and intervals[i][0] <= start:
        if intervals[i][1] > r:
            r = intervals[i][1]
            best_op = intervals[i][2]
        i += 1
    
    # 若无法推进 `start`,说明染色失败
    if r < start:
        break

    # 更新 `start` 并记录选择的操作
    start = r
    res += 1
    selected_operations.append(best_op)

    # 若已经染色到 `n`,则成功
    if r >= end:
        find = True
        break

# 输出结果
if find:
    print(res)
    print(" ".join(map(str, selected_operations)))
else:
    print('-1')

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值