2023杭电暑假多校4 题解

2023-11-19

3-Simple Set Problem

题意 k 个多重集合,每个集合选出一个数形成新集合A,求 m a x ( A ) − m i n ( A ) max(A)-min(A) max(A)min(A)

题解 排序后,滑动窗口,保证窗口里有 k 个集合的数,答案取 m i n min min 即可

#include <iostream>
#include <vector>
#include <algorithm>
#include <deque>
#define endl '\n'
#define aa first
#define bb second

using namespace std;
typedef pair<int, int> pii;
const int N = 1e6 + 2;
int n, k, c, cnt[N];

void solve() {
    n = 0;
    vector<pii> v;
    cin >> k;
    for (int i = 0; i < k; i ++) cnt[i] = 0;
    for (int i = 0; i < k; i ++) {
        cin >> c;
        n += c;
        while (c --) {
            int x; cin >> x;
            v.push_back({x, i});
        }
    }
    sort(v.begin(), v.end());
    deque<int> dq;
    int count = 0, idx = 0, res = 2e9;
    while (idx < n) {
        if (!cnt[v[idx].bb]) count ++;
        dq.push_front(idx);
        cnt[v[idx].bb] ++;
        idx ++;
        if (count < k) continue;
        while (cnt[v[dq.back()].bb] > 1) {
            cnt[v[dq.back()].bb] --;
            dq.pop_back();
        }
        res = min(res, v[dq.front()].aa - v[dq.back()].aa);
    }
    cout << res << endl;
}

int main() {
    cin.tie(0) -> sync_with_stdio(false);
    int T; cin >> T;
    while (T --) solve();
    return 0;
}

6-PSO

题意 菊花图,求每个点到别的点需要经过的边数的期望和最大值

题解
期望 = 所有组合经过的边数 组合数量 = 叶节点之间的边数 × 2 + 中心节点连着的叶节点数 叶节点之间的组合数 + 中心节点连着的叶节点数 期望=\frac{所有组合经过的边数}{组合数量}=\frac{叶节点之间的边数×2+中心节点连着的叶节点数}{叶节点之间的组合数+中心节点连着的叶节点数} 期望=组合数量所有组合经过的边数=叶节点之间的组合数+中心节点连着的叶节点数叶节点之间的边数×2+中心节点连着的叶节点数

2 × C n − 1 2 + n − 1 C n − 1 2 + n − 1 \frac{2×C_{n-1}^2+n-1}{C_{n-1}^2+n-1} Cn12+n12×Cn12+n1

最大值除了 n = 2 n=2 n=2 时最大值为 1,其余时候最大值为 2

#include <iostream>
#include <cmath>

using namespace std;
typedef long long ll;
ll n;

void solve() {
    cin >> n;
    double res = pow(n - 1, 2);
    double t = (n - 2) * (n - 1) / 2 + (n - 1);
    printf("%.9lf %.9lf\n", res / t, n == 2 ? 1.0 : 2.0);
}

int main() {
    int T; cin >> T;
    while (T --) solve();
    return 0;
}

10-Kong Ming Qi

题意 ( n + 2 ) × ( m + 2 ) (n+2)×(m+2) (n+2)×(m+2) 的棋盘,四周一圈没棋子,其余填满,若上下左右有一个棋子,可以跳到一个棋子对面(前提是本来没棋

子),并且吃掉这一个棋子

在这里插入图片描述

题解 不妨设 m ≤ n m ≤ n mn,再分类讨论:(此题解参考官方题解)

  • m = 1 m = 1 m=1 时,答案显然为 ⌈ m / 2 ⌉ ⌈m/2⌉ m/2
  • n ≥ 5 n ≥ 5 n5 时,可证明: n × m n × m n×m 等价于 ( n − 2 ) × m (n-2) × m (n2)×m

可都转换成 2 ≤ n ≤ m ≤ 4 2 ≤ n ≤ m ≤ 4 2nm4 的情形,再简单手玩得到答案

d e f def def 基本操作, n ≥ 3 n ≥ 3 n3 时,一次消去三格,可以将 n × m n × m n×m 转化为 ( n − 3 ) × m (n - 3) × m (n3)×m

在这里插入图片描述

n = 2 n = 2 n=2 时,可以将 n × m n × m n×m 转化为 ( n − 3 ) × m (n - 3) × m (n3)×m

在这里插入图片描述

证明最优用三染色引理,暂时不会(

#include <iostream>

using namespace std;
int n, m;

int ans[3][3] = {
    {1, 2, 1},
    {2, 2, 2},
    {1, 2, 1}
};

int solve() {
    cin >> n >> m;
    if (n < m) swap(n, m);
    if (m == 1) return n + 1 >> 1;
    while (n > 4) n -= 3;
    while (m > 4) m -= 3;
    return ans[n - 2][m - 2];
}

int main() {
    int T; cin >> T;
    while (T --) cout << solve() << endl;
    return 0;
}

11-Circuit

原题详见 Acwing 334.观光之旅->,但原题不需要计算最小路径的数量,有一些差异

题意 无重边无自环有向图有 n n n 个点 m m m 条边,计算最短回路的长度和数量

Tag Floyd

题解 c n t [ i ] [ j ] cnt[i][j] cnt[i][j] 表示 i i i j j j 的最短边数量

外层枚举 k k k d [ i ] [ j ] d[i][j] d[i][j] 表示除了 i i i j j j 其余点下标小于等于 k k k i i i j j j 的最短距离,再更新

对于为什么要把更新 c o u n t count count 的循环放在枚举 k k k 的循环里面,作以下解释:

首先复习以下 f l o y d floyd floyd 算法,起初是三维的,但是可以写作二维
f l o y d { 状态表示 { f [ k ] [ i ] [ j ] : 表示只经过前 k 个点 ( 不考虑 i , j 两个端点 ) 从 i 到 j 的距离 属性 : m i n 状态计算: f [ k ] [ i ] [ j ] = { f [ k − 1 ] [ i ] [ j ] : 不经过 k 从 i 到 j f [ k − 1 ] [ i ] [ k ] + f [ k − 1 ] [ k ] [ j ] : 经过 k 从 i 到 j floyd\begin{cases}状态表示\begin{cases}f[k][i][j]:表示只经过前k个点(不考虑i,j两个端点)从i到j的距离\\属性:min\end{cases}\\状态计算:f[k][i][j]=\begin{cases}f[k-1][i][j]:不经过k从i到j\\f[k-1][i][k]+f[k-1][k][j]:经过k从i到j\end{cases}\end{cases} floyd 状态表示{f[k][i][j]:表示只经过前k个点(不考虑i,j两个端点)ij的距离属性:min状态计算:f[k][i][j]={f[k1][i][j]:不经过kijf[k1][i][k]+f[k1][k][j]:经过kij

每次更新的 c n t cnt cnt 是路径 k → i → k k→i→k kik 的长度,首先看 w [ k ] [ i ] w[k][i] w[k][i] 是否存在,然后枚举 i < k i<k i<k,是为了防止重复计算路径 i → k → i i→k→i iki 的长度(与路径 k → i → k k→i→k kik 相同)。上述只考虑了路径长度为 2 2 2,但是当路径长度多起来,例如 k → i → j → k k→i→j→k kijk,有 i < k < j i<k<j i<k<j 时,会发现仍然会重复计算,所以不能只保证 k k k 确定时枚举 i < k i<k i<k,还要保证经过的点都要小于 k k k,不重不漏原则。

e . g . e.g. e.g. 如下图,枚举 k = 4 k=4 k=4 的时候,有路径 4 → 1 → 2 → 4 4→1→2→4 4124 4 → 3 → 4 4→3→4 434 4 → 1 → 5 → 4 4→1→5→4 4154;但是枚举 k = 5 k=5 k=5 时也发现会美剧到路径 5 → 4 → 1 → 5 5→4→1→5 5415,可能会出现重复计算

在这里插入图片描述

#include <iostream>

using namespace std;
typedef long long ll;
const int mod = 998244353, N = 502;
const ll inf = 1e12;
int n, m, w[N][N], cnt[N][N];
ll d[N][N];

void solve() {
    cin >> n >> m;
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= n; j ++)
            w[i][j] = 0, d[i][j] = inf;
    for (int i = 1; i <= n; i ++) d[i][i] = 0;
    while (m --) {
        int a, b, c; cin >> a >> b >> c;
        w[a][b] = d[a][b] = c;
        cnt[a][b] = 1;
    }
    ll minn = inf, count = 0;
    for (int k = 1; k <= n; k ++) {
        for (int i = 1; i <= n; i ++) {
            for (int j = 1; j <= n; j ++) {
                if (d[i][j] > d[i][k] + d[k][j]) {
                    d[i][j] = d[i][k] + d[k][j];
                    cnt[i][j] = 1ll * cnt[i][k] * cnt[k][j] % mod;
                } else if (d[i][j] == d[i][k] + d[k][j]) {
                    cnt[i][j] = (cnt[i][j] + 1ll * cnt[i][k] * cnt[k][j]) % mod;
                }
            }
        }
        for (int i = 1; i < k; i ++) {
            if (w[k][i]) {
                if (w[k][i] + d[i][k] < minn) {
                    minn = w[k][i] + d[i][k];
                    count = cnt[i][k];
                } else if (w[k][i] + d[i][k] == minn) {
                    count = (count + cnt[i][k]) % mod;
                }
            }
        }
    }
    if (minn == inf) minn = count = -1;
    cout << minn << ' ' << count << endl;
}

int main() {
    cin.tie(nullptr) -> sync_with_stdio(false);
    int T; cin >> T;
    while (T --) solve();
    return 0;
}

12-a-b Problem

题意 一共 n 个石头,AB 捡石头,对应给每个人的价值不一样,要使得 V a l u e A − V a l u e B Value_A - Value_B ValueAValueB 尽可能大

Tag 贪心

题解 对于单个石头,对 A 价值为 V A V_A VA,对 B 价值为 V B V_B VB,则若 A 拾取,则对 A 的贡献度为 V A + V B V_A+V_B VA+VB,故对两者相加逆序排序即可

#include <iostream>
#include <vector>
#include <algorithm>
#define aa first
#define bb second

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 2;
int n, a[N], b[N];
vector<pii> c(N);

ll solve() {
    cin >> n;
    for (int i = 0; i < n; i ++) {
        cin >> a[i] >> b[i];
        c[i] = {a[i] + b[i], i};
    }
    sort(c.begin(), c.begin() + n);
    ll res = 0;
    for (int i = n - 1, idx = 1; i >= 0; i --, idx ++) {
        if (idx & 1) res += a[c[i].bb];
        else res -= b[c[i].bb];
    }
    return res;
}

int main() {
    int T; cin >> T;
    while (T --) cout << solve() << endl;
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2023杭电暑假多校4 题解 的相关文章

随机推荐

  • 如何用微信自动添加wifi连接服务器地址,微信服务号如何实现扫码自动连接WIFI?详细步骤介绍!...

    微信服务号如何实现扫码自动连接WIFI 详细步骤介绍 有的朋友在运营这个微信公众号的时候 会想着如果有更多人关注自己的运营号就好了 但有的朋友没有找到好的办法 不知道如何吸引更多人的关注 下面小编给大家提供一个思路 就是当大家在关注微信公众
  • 移动端证件识别OCR

    证件识别利用的是ocr识别原理 也就是光学字符识别 证件识别方法有很多 先说第一种 用一个读港澳通行证的仪器就行 而且连上系统还能直接把信息导出成EXCEL文档 其实这个仪器叫做证件识别仪 可以识别护照 港澳通行证 台胞证 身份证 驾驶证
  • python pyplot logscale 画图对数

    原文来自公众号 工程师看海 事情的起因是我要在公众号 工程师看海 更新一篇文章 介绍电感 磁珠的区别 需要画阻抗 频率曲线 横坐标频率要按照log对数尺度缩放 就写了python代码 废话不多说 先看结果 公众号后台回复 python lo
  • 【Xilinx DDR3 MIG】Xilinx FPGA DDR3读写实验相关用户接口引脚解释

    目录 DDR3读写实验 实验框图 时钟模块 DDR3读写及LED指示模块 MIG IP核 用户接口解释
  • Python自定义异常 Python Custom Exception

    个人主页 Aurora 如果文章有什么需要改进的地方还请各位大佬指正 如果我的文章对你有帮助 关注 点赞 收藏 一 python自定义异常 1 自定义一个CustomException类 继承Exception类 2 编写CustomExc
  • cur.execute(sql,args)和cur.execute(sql)的区别

    python代码示例 方式一 userid 123 sql select id name from user where id s userid cur execute sql 方式二 sql语句模板中的参数填充符是 s 而不是 s 且多个
  • Linux上开发常见问题整理

    Linux上开发常见问题整理 1 java工程在linux上运行测试 首先要有一个main方法作为主类 程序的入口 右键 gt Run As gt javaapplication生成配置文件入口 右键该工程 gt Export gt Run
  • LaTeX 多行公式、公式对齐以及输入矩阵的方法

    一 LaTex显示 大括号连接的 多行公式 公式组合 使用cases环境实现公式的组合 分隔公式和条件 具体LaTex代码如下 D x begin cases lim limits x to 0 frac a x b c x lt 3 pi
  • tshark 解析pcap中带TLS协议的数据包

    tshark的简单用法参考 tshark解析本地pcap数据包提取五元组 src ip src port proto dst ip dst port 与时间戳 包长 详细用法 官方DOC 比如提取一个数据包 my pcap 中全部带有TLS
  • Oracle数据恢复:强制Resetlogs的可能数据损失

    Oracle数据恢复 强制Resetlogs的可能数据损失 Oracle数据恢复 格式化 ASM及字典损坏案例三则 ORA 00600 kcratr nab less than odr案例一则 SMON recover undo segme
  • 简易DOCKER/K8S使用心得

    1 DOCKER安装 1 1 前置环境 首先 如果使用CentOS 你至少需要7 4以上 从内核角度来说 建议使用8 2及以上 如果是7 4以下的版本 可以通过设置仓库到7 4以上版本 再 yum install centos releas
  • 计算机内存数值存储方式-原码、反码、补码、数值溢出

    计算机内存数值存储方式 1 原码 一个数的原码 原始的二进制码 有如下特点 最高位做为符号位 0表示正 为1表示负 其它数值部分就是数值本身绝对值的二进制数 负数的原码是在其绝对值的基础上 最高位变为1 下面数值以1字节的大小描述 原码表示
  • 手把手教你实现一个向量

    文章目录 什么是向量 向量提供哪些接口 实现 宏定义 定义类 成员变量 构造函数与析构函数 构造函数 析构函数 成员函数 size get r put r e expand insert r e remove lo hi remove r
  • nodejs获取时间戳

    可以使用 JavaScript 内置的 Date 对象来获取当前的时间戳 可以使用 Date now 方法来获取当前的时间戳 consttimestamp Date now console log timestamp 也可以使用 Date
  • 轻松掌握Python自动化工具,解锁PyAutoGUI的强大功能

    前言 PyAutoGUI是一个用于图像识别和鼠标 键盘控制的Python库 它提供了一组函数和方法 用于自动化屏幕上的鼠标移动 点击 拖拽和键盘输入 以及执行图像识别和处理 本文旨在帮助读者入门 PyAutoGUI 理解其基础概念和掌握最佳
  • js逆向-国密SM2初探

    目录 前言 目标网站 加密分析 加密定位 结尾 本文仅供学习使用 切勿非法使用 如有侵权请联系作者及时删除 前言 无意中看到一个网站采用国密SM2算法进行登陆参数进行加密 之前接触的加密基本都是国外的算法 例如RSA DES MD5等等 国
  • 13位时间戳单位为毫秒,10位字符串单位为秒。时间戳转换日期数字格式100%全乎

    时间戳转换为年月日时分秒数字格式 注意时间戳有2种 13位时间戳 单位为毫秒 10位字符串 单位为秒 接口返回1616160878418 微秒 期望格式2021 03 19 21 34 35 标签 java new Date 变成GMT G
  • tar打包备份+ubuntu系统的修复

    如果ubuntu系统出问题 通过备份文件可以简单快速地修复ubuntu系统 tar打包十分必要 一 tar打包备份 1 进入管理员账户 sudo su 2 打包 tar cvPzf 20191203ubuntu1804 tgz exclud
  • 关于static 的各种数据类型 及在面向对象编程中的应用

    一 按存储区域分 全局变量 静态全局变量和静态局部变量都存放在内存的静态存储区域 局部变量存放在内存的栈区 1定义全局静态变量的好处 lt 1 gt 不会被其他文件所访问 修改 lt 2 gt 其他文件中可以使用相同名字的变量 不会发生冲突
  • 2023杭电暑假多校4 题解

    3 Simple Set Problem 题意 k 个多重集合 每个集合选出一个数形成新集合A 求 m a x A m