小红书笔试真题 9.10 - 最小化峰值干扰(C++/Py/Java /Js/Go)

最小化峰值干扰

小红书 9月10号 笔试真题 第一题

题目描述

要将 mmm 项探测任务按给定顺序安排到连续 nnn 个时隙。第 jjj 个时隙的干扰强度为 aja_jaj,第 iii 项任务占用连续 bib_ibi 个时隙。记 lil_ili 为第 iii 项任务的起始时隙,则其占用区间为 li,li+bi−1l_i,l_i+b_i-1li,li+bi−1。

安排须满足:

  1. 任务占用互不重叠:对任意 i<ji<ji<j,有 li+bi−1<ljl_i+b_i-1<l_jli+bi−1<lj;任务之间可空出任意个时隙。
  2. 任务保持给定顺序:l1<l2<⋯<lml_1<l_2<\dots<l_ml1<l2<⋯<lm。
  3. 均落在时隙范围内:1≤li1\le l_i1≤li 且 li+bi−1≤nl_i+b_i-1\le nli+bi−1≤n。
    峰值干扰为
    max⁡i=1mmax⁡j=lili+bi−1aj\max_{i=1}^{m}\max_{j=l_i}^{l_i+b_i-1} a_jmaxi=1mmaxj=lili+bi−1aj
    求所有合法安排下峰值干扰的最小值。

输入描述

第一行一个正整数 TTT,表示测试数据组数。

对于每组测试数据:

第一行两个正整数 n,mn,mn,m,表示时隙数和任务数。

第二行 nnn 个正整数 a1,a2,...,ana_1,a_2,\dots,a_na1,a2,...,an,表示每个时隙的干扰强度。

第三行 mmm 个正整数 b1,b2,...,bmb_1,b_2,\dots,b_mb1,b2,...,bm,表示每项任务占用的时隙数。

输出描述

对于每组测试数据,输出一行一个整数,表示峰值干扰的最小值。

样例1

输入

复制代码
2
7 2
8 1 3 5 2 1 4
2 3
6 3
2 8 1 1 3 1
1 1 2

输出

复制代码
4
3

说明

第一组:第一项任务放在 2,32,32,3(覆盖 1,31,31,3,最大值 333),第二项放在 5,75,75,7(覆盖 2,1,42,1,42,1,4,最大值 444)。峰值干扰为 max⁡(3,4)=4\max(3,4)=4max(3,4)=4。若要求峰值不超过 333,则时隙 111、444、777 不可用,剩余连续段长度不足以放下长度为 333 的第二项任务。

第二组:三项任务分别放在时隙 111、333 与 4,54,54,5(覆盖 222;111;1,31,31,3),峰值干扰为 max⁡(2,1,3)=3\max(2,1,3)=3max(2,1,3)=3。若要求峰值不超过 222,则时隙 222、555 不可用,无法为第三项任务找到长度为 222 的连续段。

数据范围

1≤T≤2000001\le T\le 2000001≤T≤200000,所有测试数据的 nnn 之和 ≤200000\le 200000≤200000,1≤n1\le n1≤n,1≤m1\le m1≤m,1≤ai≤1091\le a_i\le 10^91≤ai≤109,1≤bi≤n1\le b_i\le n1≤bi≤n,∑bi≤n\sum b_i\le n∑bi≤n。

题解和思路

思路

实现思路:二分

  1. 峰值x的大小具备单调性,所以可以使用二分,规律为
    • 如果x可以满足分配,那么更大的x一定可以满足分配
    • 如果x不可以满足分配,那么更小的x一定不可以满足分配。
  2. 判断x枚举的是否可行,直接进行贪心线性分配检验就行,从左至右扫描连续a[i] <= x的长度,当长度满足当前待分配任务时,就进行分配。最终检验是否所有任务都可以被分配就行。
  3. 时间复杂度为O(nlog)

C++

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

// 贪心线性检验不超过x情况能否全部分配
bool check(int x, vector<int>& a, vector<int>& b) {
    int n = a.size();
    int m = b.size();
    
    int id = 0;
    int len = 0;
    for (int i = 0; i < n; i++) {
        if (a[i] <= x) {
            len++;
            if (len == b[id]) {
                id++;
                len = 0;
                if (id == m) {
                    return true;
                }
            }
        } else {
            len = 0;
        }
    }
    return false;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int T;
    cin >> T;
    while (T--) {
        int n,m;
        cin >> n >> m;
        vector<int> a(n), b(m);
        
        int mx = 0;
        
        for (int i = 0; i < n; i++){
            cin >> a[i];
            mx = max(mx, a[i]);
        }
        for(int i = 0; i < m; i++) {
            cin >> b[i];
        }
        int l = 1, r = mx;
        // 二分枚举
        while (l < r) {
            int mid = (l + r) >> 1;
            if (check(mid, a, b)) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        cout << l << endl;
    }
    return 0;
}

Java

java 复制代码
import java.io.*;
import java.util.*;

// 贪心线性检验不超过x情况能否全部分配
public class Main {
    static boolean check(int x, int[] a, int[] b) {
        int n = a.length;
        int m = b.length;

        int id = 0;
        int len = 0;
        for (int i = 0; i < n; i++) {
            if (a[i] <= x) {
                len++;
                if (len == b[id]) {
                    id++;
                    len = 0;
                    if (id == m) {
                        return true;
                    }
                }
            } else {
                len = 0;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int T = sc.nextInt();
        while (T-- > 0) {
            int n = sc.nextInt();
            int m = sc.nextInt();

            int[] a = new int[n];
            int[] b = new int[m];

            int mx = 0;

            for (int i = 0; i < n; i++) {
                a[i] = sc.nextInt();
                mx = Math.max(mx, a[i]);
            }

            for (int i = 0; i < m; i++) {
                b[i] = sc.nextInt();
            }

            int l = 1, r = mx;
            // 二分枚举
            while (l < r) {
                int mid = (l + r) >> 1;
                if (check(mid, a, b)) {
                    r = mid;
                } else {
                    l = mid + 1;
                }
            }

            System.out.println(l);
        }
    }
}

python

python 复制代码
# 贪心线性检验不超过x情况能否全部分配
def check(x, a, b):
    n = len(a)
    m = len(b)

    id = 0
    length = 0
    for i in range(n):
        if a[i] <= x:
            length += 1
            if length == b[id]:
                id += 1
                length = 0
                if id == m:
                    return True
        else:
            length = 0
    return False


T = int(input())

for _ in range(T):
    n, m = map(int, input().split())
    a = list(map(int, input().split()))
    b = list(map(int, input().split()))

    mx = max(a)

    l, r = 1, mx
    # 二分枚举
    while l < r:
        mid = (l + r) >> 1
        if check(mid, a, b):
            r = mid
        else:
            l = mid + 1

    print(l)

Javascript

js 复制代码
const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

const input = [];

rl.on('line', line => {
    input.push(...line.trim().split(/\s+/));
});

rl.on('close', () => {
    let pos = 0;
    let T = Number(input[pos++]);
    const ans = [];

    // 贪心线性检验不超过x情况能否全部分配
    function check(x, a, b) {
        const n = a.length;
        const m = b.length;

        let id = 0;
        let len = 0;

        for (let i = 0; i < n; i++) {
            if (a[i] <= x) {
                len++;
                if (len === b[id]) {
                    id++;
                    len = 0;
                    if (id === m) {
                        return true;
                    }
                }
            } else {
                len = 0;
            }
        }

        return false;
    }

    while (T-- > 0) {
        const n = Number(input[pos++]);
        const m = Number(input[pos++]);

        const a = new Array(n);
        const b = new Array(m);

        let mx = 0;

        for (let i = 0; i < n; i++) {
            a[i] = Number(input[pos++]);
            mx = Math.max(mx, a[i]);
        }

        for (let i = 0; i < m; i++) {
            b[i] = Number(input[pos++]);
        }

        let l = 1;
        let r = mx;

        // 二分枚举
        while (l < r) {
            const mid = Math.floor((l + r) / 2);

            if (check(mid, a, b)) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }

        ans.push(l);
    }

    console.log(ans.join('\n'));
});

Go

go 复制代码
package main

import (
	"bufio"
	"fmt"
	"os"
)

// 贪心线性检验不超过x情况能否全部分配
func check(x int, a []int, b []int) bool {
	n := len(a)
	m := len(b)

	id := 0
	length := 0
	for i := 0; i < n; i++ {
		if a[i] <= x {
			length++
			if length == b[id] {
				id++
				length = 0
				if id == m {
					return true
				}
			}
		} else {
			length = 0
		}
	}
	return false
}

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var T int
	fmt.Fscan(in, &T)

	for ; T > 0; T-- {
		var n, m int
		fmt.Fscan(in, &n, &m)

		a := make([]int, n)
		b := make([]int, m)

		mx := 0

		for i := 0; i < n; i++ {
			fmt.Fscan(in, &a[i])
			if a[i] > mx {
				mx = a[i]
			}
		}

		for i := 0; i < m; i++ {
			fmt.Fscan(in, &b[i])
		}

		l, r := 1, mx

		// 二分枚举
		for l < r {
			mid := (l + r) >> 1
			if check(mid, a, b) {
				r = mid
			} else {
				l = mid + 1
			}
		}

		fmt.Fprintln(out, l)
	}
}
相关推荐
无限码力8 小时前
小红书笔试真题 9.10 - 双通道评测格网(C++/Py/Java /Js/Go)
小红书笔试·小红书笔试真题·小红书笔试题解·小红书校招笔试题目
feasibility.7 天前
MediaCrawler媒体采集平台安装与使用
爬虫·抖音·小红书·微博·bili
程序猿炎义3 个月前
一人内容团队——用Amazon Quick Desktop实现小红书从选题到发布的全流程自动化
大数据·人工智能·microsoft·自动化·小红书
小脑斧1234 个月前
AI Skills 全链路自动化运营实践:抖音热点、小红书种草与文生图一体化方案
大数据·人工智能·小红书·skills·自动化运营
Afans_fire4 个月前
从数据角度优化全媒体广告投放
小红书·广告投放·抖音运营·抖音代运营·小红书聚光
Afans_fire4 个月前
全域流量时代:如何用“漏斗模型”打通百度、抖音与小红书的营销闭环?
百度·内容运营·小红书·小红书运营·广告投放·巨量引擎
yoona10205 个月前
使用 Auto-Redbook-Skills 自动生成并发布redbook图文笔记
笔记·小红书·skills·redbook
深蓝电商API5 个月前
小红书商品笔记抓取:笔记ID与商品关联关系解析
爬虫·小红书
Neolnfra6 个月前
用 QClaw 自动化运营小红书:对话式操控全攻略
小红书·openclaw·qclaw