CCF CAT- 全国算法精英大赛(2024第二场)往届真题练习 4 | 珂学家

news2024/11/18 9:30:22

前言

在这里插入图片描述



餐馆

在这里插入图片描述

思路:可撤销的0-1背包

考察了多个知识点,包括

  • 差分技巧
  • 离线思路
  • 0-1背包

不过这题卡语言,尤其卡python

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Main {

    static final long mod = (long)1e9 + 7;

    public static void main(String[] args) {
        AReader scanner = new AReader();
        PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));

        // 读取n和v
        int n = scanner.nextInt();
        int v = scanner.nextInt();

        // 读取并处理物品信息
        List<int[]> packs = new ArrayList<>();
        List<int[]> ops = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            int s = scanner.nextInt();
            int e = scanner.nextInt();
            int w = scanner.nextInt();
            packs.add(new int[]{s, e, w});
            ops.add(new int[]{s, 1, w});
            ops.add(new int[]{e + 1, -1, w});
        }

        // 对ops按时间排序
        ops.sort(Comparator.comparingInt(a -> a[0]));

        // 读取q和查询时间
        int q = scanner.nextInt();
        int[] arr = IntStream.range(0, q).map(i -> scanner.nextInt()).toArray();

        // 将查询和索引关联起来
        List<int[]> qs = IntStream.range(0, q).mapToObj(i -> new int[]{arr[i], i}).collect(Collectors.toList());
        qs.sort(Comparator.comparingInt(a -> a[0]));

        // 互斥的两类
        long[] dp1 = new long[v + 1];
        long[] dp2 = new long[v + 1];

        // 初始化dp2
        dp2[0] = 1;
        for (int[] pack : packs) {
            int s = pack[0];
            int w = pack[2];
            for (int m = v - w; m >= 0; m--) {
                dp2[m + w] += dp2[m];
                dp2[m + w] %= mod;
            }
        }
        dp1[0] = 1;

        // 双指针,离散做法
        int p1 = 0;
        int p2 = 0;
        int[][] res = new int[q][2];
        for (int i = 0; i < 101; i++) { // 假设结束时间不超过arr[q-1]
            while (p1 < ops.size() && ops.get(p1)[0] <= i) {
                int[] op = ops.get(p1);
                int d = op[1];
                int w = op[2];
                if (d == 1) {
                    add01(dp1, w, v);
                    remove01(dp2, w, v);
                } else {
                    remove01(dp1, w, v);
                    add01(dp2, w, v);
                }
                p1++;
            }

            // 找到fz和bz
            int fz = 0;
            for (int j = v; j >= 0; j--) {
                if (dp1[j] > 0) {
                    fz = j;
                    break;
                }
            }
            int bz = 0;
            for (int j = v - fz; j >= 0; j--) {
                if (dp2[j] > 0) {
                    bz = j;
                    break;
                }
            }

            // 填充结果
            while (p2 < qs.size() && qs.get(p2)[0] <= i) {
                res[qs.get(p2)[1]][0] = fz;
                res[qs.get(p2)[1]][1] = bz;
                p2++;
            }
        }

        // 输出结果
        for (int[] pair : res) {
            out.println(pair[0] + " " + pair[1]);
        }
        out.flush();
        out.close();
    }

    private static void add01(long[] dp, int w, int v) {
        for (int u = v - w; u >= 0; u--) {
            dp[u + w] += dp[u];
            dp[u + w] %= mod;
        }
    }

    private static void remove01(long[] dp, int w, int v) {
        for (int u = 0; u <= v - w; u++) {
            dp[u + w] -= dp[u];
            dp[u + w] = (dp[u + w] % mod + mod) % mod;
            // 注意:在Java中,如果dp[u]是0或负数,可能需要额外的逻辑来避免负数
        }
    }

    static
    class AReader {
        private BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        private StringTokenizer tokenizer = new StringTokenizer("");
        private String innerNextLine() {
            try {
                return reader.readLine();
            } catch (IOException ex) {
                return null;
            }
        }
        public boolean hasNext() {
            while (!tokenizer.hasMoreTokens()) {
                String nextLine = innerNextLine();
                if (nextLine == null) {
                    return false;
                }
                tokenizer = new StringTokenizer(nextLine);
            }
            return true;
        }
        public String nextLine() {
            tokenizer = new StringTokenizer("");
            return innerNextLine();
        }
        public String next() {
            hasNext();
            return tokenizer.nextToken();
        }
        public int nextInt() {
            return Integer.parseInt(next());
        }
        public long nextLong() {
            return Long.parseLong(next());
        }
    }

}

python 版本被卡常

# coding=utf-8
# coding=utf-8
import sys
input=sys.stdin.buffer.readline

n, v = list(map(int, input().split()))

ops = []
packs = []
for i in range(n):
    s, e, w = list(map(int, input().split()))
    packs.append((s, e, w))
    ops.append((s, 1, w))
    ops.append((e + 1, -1, w))
ops.sort(key=lambda x: x[0])

t1, t2 = 100, 0
q = int(input())
arr = list(map(int, input().split()))
qs = []
for i in range(q):
    qs.append((arr[i], i))
    t1 = min(t1, arr[i])
    t2 = max(t2, arr[i])
qs.sort(key=lambda x: [0])

# 互斥的两类
dp1 = [0] * (v + 1)
dp2 = [0] * (v + 1)

#--------------------------------

dp2[0] = 1
for (s, e, w) in packs:
    for m in range(v - w, -1, -1):
        dp2[m + w] += dp2[m]

dp1[0] = 1

def add01(dp, w):
    for u in range(v - w, -1, -1):
        dp[u + w] += dp[u]

def remove01(dp, w):
    for u in range(0, v - w + 1):
        dp[u + w] -= dp[u]

# 双指针,离散做法
res = [[]] * q
p1, p2 = 0, 0
for i in range(t1, t2 + 1):
    while p1 < len(ops) and ops[p1][0] <= i:
        d = ops[p1][1]
        if d == 1:
            add01(dp1, ops[p1][2])
            remove01(dp2, ops[p1][2])
        elif d == -1:
            remove01(dp1, ops[p1][2])
            add01(dp2, ops[p1][2])
        p1 += 1

    # print (i, dp1, dp2)

    fz = max([i for i in range(v + 1) if dp1[i] > 0])
    bz = max([i for i in range(v + 1) if dp2[i] > 0 and i <= (v - fz)])

    while p2 < len(qs) and qs[p2][0] <= i:
        res[qs[p2][1]] = (fz, bz)
        p2 +=  1

# for (fz, bz) in res:
#     print (fz, bz)

print ("\n".join(map(lambda x: str(x[0]) + " "+ str(x[1]), res)))

写在最后

在这里插入图片描述

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

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

相关文章

Java实现异步的4种方式

文章目录 异步1、Future与Callable2. CompletableFuture3. Spring框架的异步支持3.1 启动类开启对Async的支持 EnableAsync3.2 配置自定义线程池3.3 异步业务3.4 调用异步业务方法 4. 使用消息队列4.1 安装RabbitMq4.2 使用4.3 MQ消息丢失以及重复消费问题 5、总结 异步 异步&…

vue3 调用本地exe

1、注册表注册 在注册表中直接按照图2注册数据&#xff1b;也可以按照图3注册表的文件创建文档&#xff0c;然后点击打开&#xff0c;将会将注册表写入window系统。 图2 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\F1] "URL:F1 Protocol Handler" &q…

Ansible03-Ansible Playbook剧本详解

目录 写在前面5. Ansible Playbook 剧本5.1 YAML语法5.1.1 语法规定5.1.2 示例5.1.3 YAML数据类型 5.2 Playbook组件5.3 Playbook 案例5.3.1 Playbook语句5.3.2 Playbook1 分发hosts文件5.3.3 Playbook2 分发软件包&#xff0c;安装软件包&#xff0c;启动服务5.3.3.1 任务拆解…

通过ESP32芯片模组实现产品智能化升级,启明云端乐鑫代理商

随着科技的不断进步&#xff0c;物联网&#xff08;IoT&#xff09;已经渗透到我们生活的方方面面&#xff0c;成为现代生活不可或缺的一部分。在这场智能化革命中&#xff0c;乐鑫科技以其创新的ESP32芯片模组&#xff0c;为智能家居和智能设备的发展注入了新的活力。作为乐鑫…

一次绕过waf进行xss的经历

今天室友遇到一个好玩的网站&#xff0c;下面是一些尝试绕过Waf进行XSS的记录。首先该网站没有对左右尖号和单双引号做任何过滤或转义。且有未知的waf或者其他阻止恶意访问的手段。 首先我的访问为 login.asp?f1 时候&#xff0c;页面关键源码为 可能是表示登录次数的一个东西…

简单模拟实现shell(Linux)

目录​​​​​​​ 前言 展示效果 实现代码 前言 该代码模拟了shell的实现&#xff0c;也就是解析类似于“ls -a -l"的命令&#xff0c;当我们启动我们自己写的shell的可执行程序时&#xff0c;我们输入"ls"的命令&#xff0c;也可以展示出在shell中输入&…

广告联盟收款的解决方案

目前国内的affiliate&#xff0c;收海外联盟款就六种主要的解决方案(使用何种方式收款&#xff0c;不是我们决定的&#xff0c;是你操作的联盟决定的&#xff0c;你要根据联盟的要求提供相应的收款方式) 1 直接注册国外当地的银行账户 比如我收美国的广告联盟佣金用的是我美国银…

【设计模式】JAVA Design Patterns——Dependency Injection(依赖注入模式)

&#x1f50d;目的 依赖注入是一种软件设计模式&#xff0c;其中一个或多个依赖项&#xff08;或服务&#xff09;被注入或通过引用传递到一个依赖对象&#xff08;或客户端&#xff09;中&#xff0c;并成为客户端状态的一部分。该模式将客户的依赖关系的创建与其自身的行为分…

Java集合—TreeSet和TreeMap

一、TreeSet 1.当使用无参构造器&#xff0c;创建TreeSet时&#xff0c;仍然是无序的。 2.若希望添加的元素有序&#xff0c;需要使用TreeSet提供的构造器,传入一个比较器。 该比较器是一个接口&#xff0c;里面有一个方法叫compare()&#xff0c;传入一个实现该接口的类(匿名内…

使用PyAutoGUI识别PNG图像并自动点击按钮

在自动化测试、任务批处理等场景中,我们常常需要控制GUI程序的鼠标键盘操作。PyAutoGUI就是一个非常方便的Python模块,可以帮助我们实现这些操作。今天我们就来看看如何使用PyAutoGUI识别屏幕上的PNG图像,并自动点击图像所在位置。 C:\pythoncode\new\autoguirecongnizepng.py …

树--搜索二叉树

现有一棵结点数目为n的二叉树&#xff0c;采用二叉链表的形式存储。对于每个结点均有指向左右孩子的两个指针域&#xff0c;而结点为n的二叉树一共有n-1条有效分支路径。那么&#xff0c;则二叉链表中存在2n-(n-1)n1个空指针域。那么&#xff0c;这些空指针造成了空间浪费。 例…

Redis 中 Set 数据结构详解

用法 Redis 中的 Set 是一个无序&#xff0c;不重复集合&#xff08;里面的元素为字符串&#xff09;&#xff0c;支持常用的集合操作。 常见命令 1. 增 添加一个或多个元素到 set 中 SADD key member [ member ... ] 返回值&#xff1a; 添加成功的元素个数 将一个元素移到…

react跨组件通信Context

案例&#xff1a;现在有个父-子-孙组件 需要进行组件通信 import { useState } from "react"; // 创建上下文 const CountContext React.createContext();//子组件 const SonComponent (props) > {return (<div><h2>子组件</h2><Grandson…

spdlog 使用

spdlog 是一个日志库&#xff0c;直接引用头文件即可使用&#xff0c;速度快&#xff0c;异步打印日志。 对应的git地址 spdloggit地址 对应的目录 把上面划线的文件夹引入到自己的工程中&#xff0c;即可使用spdlog 下面是使用例子 inline static void create_logging(const…

LeetCode hot100-57-G

17. 电话号码的字母组合 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。不会&#xff0c;放IDEA里执行了一下大概理解了流程 …

Django序列化器中validate没起作用?validate的触发时机

今天上班的时候分配了一个任务&#xff0c;是修复前端的一个提示优化&#xff0c;如下图所示&#xff1a; 按照以往的经验我以为可以直接在validate上进行校验&#xff0c;如何抛出一个异常即可 &#xff0c;例如&#xff1a; class CcmSerializer(serializers.ModelSerialize…

划重点来了,计算机组成原理之计算机存储介绍与汉明码纠错

存储器 1. 分类 &#xff08;1&#xff09;按存储介质分类&#xff1a; 存储介质是能寄存”0“或"1"两种代码的物质或元器件。 包括半导体器件&#xff0c;磁性材料&#xff0c;光盘等。 半导体存储器&#xff1a;半导体器件组成的存储器。断电后数据会丢失&…

关于Word目录的更新

左侧标题顺序如有调整&#xff0c;自动目录并不会同步更新&#xff0c;每次都要记得在正文目录左上角点击更新目录

【Linux终端探险】:从入门到熟练,玩转基础命令的秘密(一)

文章目录 &#x1f680;Linux基础命令⭐1. 查看目录命令&#x1f4a5;2. 切换目录&#x1f44a;3. 创建目录❤️4. 删除目录/文件&#x1f6b2;5. 修改目录/文件&#x1f308;6. 拷贝目录/文件 &#x1f680;Linux基础命令 ⭐1. 查看目录命令 在Linux中&#xff0c;查看目录的…

【Paddle】Inplace相关问题:反向传播、影响内存使用和性能

【Paddle】Inplace相关问题&#xff1a;反向传播、影响内存使用和性能 写在最前面inplace 的好处有哪些&#xff1f;能降低计算复杂度吗在反向传播时&#xff0c;Inplace为什么会阻碍呢&#xff1f;“计算图的完整性受损”表达有误原地操作 sin_()为什么原地操作会阻碍反向传播…