2022杭电多校(十)

2023-11-04

2022杭电多校(十)

一、比赛小结

比赛链接:Problems (hdu.edu.cn)

二、题目分析及解法(基础题)

1001、Winner Prediction

题目链接:Problem - 7244 (hdu.edu.cn)

题意:

有 n 个人在打比赛,现在已经有 m1 场比赛胜负已定, 有 m 2 场比赛胜负未知,一个人获得冠军的条件是没有人赢得比赛的次数大于他,问 1 号选手是否有可能赢得冠军

题解:

先让 1 号选手赢下所有和他有关的比赛,设此时选手 i 赢了 a i a_i ai 场比赛。如果存在某个 a i > a i + 1 a_i>a_{i+1} ai>ai+1 则 1 号选手不可能成为冠军。否则选手 i i i 至多还能再赢 b i = a 1 − a i b_i=a_1-a_i bi=a1ai 场比赛。考虑建立一张网络流图:每场未进行的比赛在图中用一个点表示,源点向它连容量为 1 的边,它向它的两个参赛选手的对应点各自连容量为 1 的边;选手 i 的对应点向汇点连容量为 b i b_i bi 的边。计算该图最大流,若源点出发的边满流则答案为 YES ,否则为 NO 。

代码:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N = 505;
int n, T, m1, m2, s[N];
namespace Flow {
struct Edge {
  int To, Val, Nxt;
} Ed[10005];
int n, S, T, Head[2005], cur[2005], dis[2005], cnt;
void AddEdge(int x, int y, int val) {
  // printf("AddEdge(%d,%d,%d)\n", x, y, val);
  Ed[++cnt] = (Edge){y, val, Head[x]};
  Head[x] = cnt;
  Ed[++cnt] = (Edge){x, 0, Head[y]};
  Head[y] = cnt;
}
bool bfs() {
  for (int i = 1; i <= n; i++) dis[i] = 1e9;
  queue<int> Q;
  Q.push(S);
  dis[S] = 0;
  while (!Q.empty()) {
    int Now = Q.front();
    Q.pop();
    for (int i = Head[Now]; i != -1; i = Ed[i].Nxt) {
      if (dis[Ed[i].To] == 1e9 && Ed[i].Val) {
        Q.push(Ed[i].To);
        dis[Ed[i].To] = dis[Now] + 1;
      }
    }
  }
  return dis[T] != 1e9;
}
int dfs(int x, int val) {
  if (x == T || val == 0) {
    return val;
  }
  int Out = 0;
  for (int &i = cur[x]; i != -1; i = Ed[i].Nxt) {
    if (dis[Ed[i].To] != dis[x] + 1 || !Ed[i].Val) continue;
    int tmp = dfs(Ed[i].To, min(val, Ed[i].Val));
    val -= tmp;
    Out += tmp;
    Ed[i].Val -= tmp;
    Ed[i ^ 1].Val += tmp;
    if (val == 0) break;
  }
  return Out;
}
int Dinic() {
  int ans = 0;
  while (bfs()) {
    memcpy(cur, Head, sizeof(cur));
    ans += dfs(S, 1e9);
  }
  return ans;
}
}  // namespace Flow
int main() {
  // freopen("1001.in", "r", stdin);
  // freopen("1001.out", "w", stdout);
  scanf("%d", &T);
  while (T--) {
    scanf("%d%d%d", &n, &m1, &m2);
    for (int i = 1; i <= n; i++) s[i] = 0;
    for (int i = 1; i <= m1; i++) {
      int x, y, z;
      scanf("%d%d%d", &x, &y, &z);
      if (z == 1)
        s[x]++;
      else
        s[y]++;
    }

    Flow::n = n + m2 + 2;
    Flow::S = n + m2 + 1;
    Flow::T = n + m2 + 2;
    Flow::cnt = -1;
    for (int i = 1; i <= Flow::n; i++) {
      Flow::Head[i] = -1;
    }

    int cnt = 0;
    for (int i = 1; i <= m2; i++) {
      int x, y;
      scanf("%d%d", &x, &y);
      if (x == 1 || y == 1) {
        cnt++;
        s[1]++;
        continue;
      }
      Flow::AddEdge(n + i, x, 1);
      Flow::AddEdge(n + i, y, 1);
      Flow::AddEdge(Flow::S, n + i, 1);
    }
    bool flag = true;
    for (int i = 2; i <= n; i++) {
      if (s[i] > s[1]) flag = false;
      Flow::AddEdge(i, Flow::T, s[1] - s[i]);
    }
    if (!flag) {
      printf("NO\n");
      continue;
    }
    printf(Flow::Dinic() == m2 - cnt ? "YES\n" : "NO\n");
  }
}

1003、Wavy Tree

题目链接:Problem - 7246 (hdu.edu.cn)

题意:

给你一个长度为 n 的数组,你可以对数组中任一一个元素进行 +1 / -1 的操作,问至少要做多少次操作才能使数组变成波浪数组,波浪数组,即对于每一个数 i ii 都有 a [ i ] < min ⁡ ( a [ i − 1 ] , a [ i + 1 ] )   ∨   a [ i ] > max ⁡ ( a [ i − 1 ] , a [ i + 1 ] ) a[i]<\min (a[i-1], a[i+1]) \ \lor \ a[i]>\max (a[i-1], a[i+1]) a[i]<min(a[i1],a[i+1])  a[i]>max(a[i1],a[i+1])

题解:

贪心或 d p dp dp 即可

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 1e6 + 5;
int a[maxn], b[maxn];
int n;
signed main() {
  // freopen("in.txt", "r", stdin);
  // freopen("out.txt", "w", stdout);
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
  int _;
  cin >> _;
  while (_--) {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> b[i], a[i] = b[i];
    // ↑ ↓
    // f == true -> up
    bool f1 = true;
    int ans1 = 0;
    for (int i = 2; i <= n; i++) {
      if (f1) {  // a[i] 应该上升
        if (a[i - 1] >= a[i]) {
          ans1 += (a[i - 1] + 1 - a[i]);
          a[i] = a[i - 1] + 1;
        }
      } else {  // a[i] 应该下降
        if (a[i] >= a[i - 1]) {
          ans1 += (a[i] + 1 - a[i - 1]);
          a[i] = a[i - 1] - 1;
        }
      }
      f1 = !f1;
    }
    // ↓ ↑
    bool f2 = false;
    int ans2 = 0;
    for (int i = 2; i <= n; i++) {
      if (f2) {  // a[i] 应该上升
        if (b[i - 1] >= b[i]) {
          ans2 += (b[i - 1] + 1 - b[i]);
          b[i] = b[i - 1] + 1;
        }
      } else {  // a[i] 应该下降
        if (b[i] >= b[i - 1]) {
          ans2 += (b[i] + 1 - b[i - 1]);
          b[i] = b[i - 1] - 1;
        }
      }
      f2 = !f2;
    }
    int ans = min(ans1, ans2);
    cout << ans << endl;
  }
  return 0;
}

1004、Average Replacement

题目链接:Problem - 7247 (hdu.edu.cn)

题意:

给定一张图,每个点均有点权 ω i \omega_i ωi ,假如一个点有 k k k 个邻居,点权分别为 a 1 , a 2 , . . . , a k a_1, a_2, ..., a_k a1,a2,...,ak ,那么进行一次 “交换” 后,它的权会变成 ω i + a 1 + a 2 + . . . + a k k + 1 \displaystyle \frac{\omega_i + a_1+a_2+...+a_k}{k+1} k+1ωi+a1+a2+...+ak ,经过很多次 “交换” 后,每个点的权会收敛至一个固定值,求这些值

题解:

  • 每个连通块内的数最后会趋于同一个值。

  • deg ⁡ ( i ) \deg(i) deg(i) 表示 i i i 的朋友数量,则每个连通块内 ∑ a i ( deg ⁡ ( i ) + 1 ) \sum a_i (\deg(i)+1) ai(deg(i)+1) 为一定值。

综合以上两点即可解出最后收敛到的那个值。时间复杂度 O ( n ) O(n) O(n)

代码:

#include <cstdio>
using namespace std;
int n, m, T, a[100005], deg[100005];
long long Ans[100005], Sum[100005];

int F[100005];
int Find(int x) { return F[x] == x ? x : F[x] = Find(F[x]); }
int main() {
  // freopen("1004.in","r",stdin);
  // freopen("1005.out","w",stdout);
  scanf("%d", &T);
  while (T--) {
    scanf("%d%d", &n, &m);
    // printf("-- T = %d (n,m) = %d %d\n",T,n,m);
    for (int i = 1; i <= n; i++) {
      scanf("%d", &a[i]);
      deg[i] = 0;
      F[i] = i;
      Sum[i] = Ans[i] = 0;
    }
    for (int i = 1; i <= m; i++) {
      int x, y;
      scanf("%d%d", &x, &y);
      deg[x]++;
      deg[y]++;
      if (Find(x) != Find(y)) F[Find(x)] = Find(y);
    }
    for (int i = 1; i <= n; i++) {
      Ans[Find(i)] += (long long)(deg[i] + 1) * a[i];
      Sum[Find(i)] += (deg[i] + 1);
    }
    for (int i = 1; i <= n; i++) {
      printf("%.6lf\n", (double)((long double)Ans[Find(i)] / Sum[Find(i)]));
      // printf("%lld %lld\n",Ans[Find(i)],Sum[Find(i)]);
    }
  }
}

1007、Even Tree Split

题目链接:Problem - 7250 (hdu.edu.cn)

题意:

给你一个 n n n 节点的树( n n n 是偶数),你可以从树中删除至少一条边,使得删除后各个连通块节点的个数为偶数,问有多少种删除方案。答案对 998244353 998244353 998244353 取模。

题解:

对每条边,如果删去该边后两棵树点数都为奇数,则称其为好边。显见一个边集是合法的当且仅当边集内都为好边。则答案为 2 c − 1 2^c-1 2c1 ,其中 c c c 为好边数量。时间复杂度 O ( n ) O(n) O(n)

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
const int mod = 998244353;
int num[maxn];
struct e {
  int to, next;
} edge[maxn << 1];
int head[maxn], tot;
int n;
void addedge(int u, int v) {
  edge[tot].to = v;
  edge[tot].next = head[u];
  head[u] = tot++;
}
int zhishu[maxn];
void init() {
  tot = 0;
  memset(head, -1, sizeof(head));
  zhishu[0] = 1;
  for (int i = 1; i < maxn; i++) {
    zhishu[i] = (zhishu[i - 1] * 2) % mod;
  }
}
void dfs(int u, int fa) {
  num[u] = 1;
  for (int i = head[u]; i != -1; i = edge[i].next) {
    int v = edge[i].to;
    if (v == fa) continue;
    dfs(v, u);
    num[u] += num[v];
  }
}
int main() {
  // freopen("in.txt", "r", stdin);
  // freopen("out.txt", "w", stdout);
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
  int _;
  cin >> _;
  while (_--) {
    init();
    cin >> n;
    for (int i = 1; i < n; i++) {
      int u, v;
      cin >> u >> v;
      addedge(u, v);
      addedge(v, u);
    }
    dfs(1, 0);
    int ans = 0;
    for (int i = 1; i <= n; i++) {
      if (num[i] % 2 == 0) ans++;
    }
    ans = ans - 1;
    cout << zhishu[ans] - 1 << endl;
  }
  return 0;
}

1009、Painting Game

题目链接:Problem - 7252 (hdu.edu.cn)

题意:

给一个 1 × n 的网格,Alice 和 Bob 轮流给一个网格涂成黑色,要求不能在已经涂成黑色的网格旁涂色,Alice 想最小化黑色网格数量,Bob想最大化黑色网格数量,给出 n 和先手的人,输出黑色网格数量。

题解:

我们把涂黑操作想象成剪掉连续的三个格子。如果每个连续段长度都 ≤ 2 \leq 2 2 ,那么结果事实上已经决定了。在此之前,可以发现,Alice 的一种最优策略是:选某个连续段的左数第二个格子涂黑;Bob 的一种最优策略是:选某个连续段的左数第三个格子涂黑。设 f ( n ) , g ( n ) f(n), g(n) f(n),g(n) 分别为 Alice、Bob 面对长度为 n n n 的空纸带时的答案。则有 f ( n ) = g ( n − 3 ) + 1 , g ( n ) = f ( n − 4 ) + 2 ,   n ≥ 7 f(n)=g(n-3)+1, g(n)=f(n-4)+2, \ n\geq 7 f(n)=g(n3)+1,g(n)=f(n4)+2, n7 。时间复杂度 O ( n ) O(n) O(n)

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 5;
int n;
string s;
int A[maxn], B[maxn];
void init() {
  A[1] = B[1] = A[2] = B[2] = A[3] = 1;
  A[4] = B[3] = B[4] = 2;
  for (int i = 5; i < maxn; i++) {
    A[i] = B[i - 3] + 1;
    B[i] = A[i - 4] + 2;
  }
}
int main() {
  // freopen("in.txt", "r", stdin);
  // freopen("out.txt", "w", stdout);
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
  init();
  int _;
  cin >> _;
  while (_--) {
    cin >> n >> s;
    int ans = (n - 1) / 7 * 3 + 1;
    int tmp = (n - 1) % 7 + 1;
    if (s == "Alice") {
      if (tmp >= 4) ans++;
      if (tmp >= 6) ans++;
    } else if (s == "Bob") {
      if (tmp >= 3) ans++;
      if (tmp >= 5) ans++;
    }
    cout << ans << endl;
  }
  for (int i = 1; i < 20; i++)
    cout << "i=" << i << " " << A[i] << " " << B[i] << endl;
  return 0;
}

三、题目分析及解法(进阶题)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2022杭电多校(十) 的相关文章

  • pygame从入门到放弃(一)

    首先pip 那个pygame 然后看代码 临时写的 图片就不插了 防止舍友砍我 现在是凌晨 TOC 井字棋游戏 此代码基本能立于不败之地 import random 可视化输出 def draw Board board print prin
  • gcc中预定义的宏__GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__

    今天在看Linux系统编程这本书的代码的时候看到了 GNUC 不太清楚这个宏所以去查了一下 以此记录 GNU C预定义了一系列的宏 这些宏都是以双下划线开始的 这里只讲一下 GNUC GNUC MINOR GNUC PATCHLEVEL 完
  • vue中this.$set()的用法

    1 this set 的作用 向响应式对象中添加一个属性 并确保这个新属性同样是响应式的 且触发视图更新 this set 用于向响应式对象上添加新属性 因为 Vue 无法探测普通的新增属性 简单来说 就是我们在methods中给数据添加了

随机推荐

  • 整数拆分--

    题目描述 一个整数总可以拆分为2的幂的和 例如 7 1 2 4 7 1 2 2 2 7 1 1 1 4 7 1 1 1 2 2 7 1 1 1 1 1 2 7 1 1 1 1 1 1 1 总共有六种不同的拆分方式 再比如 4可以拆分成 4
  • [每日两题系列]刷算法题咯~~

    今日题目 最小栈 有效的括号 本系列所选题目均来自力扣或者牛客网站 所选题目主要是以其中的简单题为主 中等题为辅 包含少数困难题 原因是 本人目前能力还不够 开展这个系列的目的是督促自己 在暑假的时间里也要保持有一定的刷题量 拒绝摆烂 话不
  • FISCO BCOS 联盟链Max搭建

    FISCO BCOS Max版本 版本说明 为了能够支撑海量交易上链场景 v3 0 0推出了Max版本FISCO BCOS Max版本FISCO BCOS旨在提供海量存储服务 高性能可扩展的执行模块 高可用的故障恢复机制 Max版FISCO
  • ZYNQ #2 - Linux环境下烧录BOOT.BIN从QSPI-FLASH启动

    这篇博文讲述的是在Linux环境下 将生成的新BOOT BIN利用dd指令写入板上qspi flash中 板子从flash启动后 转至SD卡执行linux内核 这篇博文是为了之后不使用SD卡 将linux内核以及根文件系统放入emmc启动做
  • Web前端复习——Javascript(字符串)

    1 什么是字符串 字符串是多个字符组成的一个 只读 的集合 数组 注意 1 凡是数组对象中 不修改原对象的API 字符串都能用 比如 length属性 字符个数 用 i 访问每个字符 slice indexof 2 凡是数组对象中 直接修改
  • DocArray 和 Redis 联手,让推荐系统飞起来

    在DocArray中使用Redis后端 基于向量相似性搜索可以快速搭建一个实时商品推荐系统 现在 跟上我们的脚步 一起了解搭建系统的关键步骤 并且深入了解推荐的原理吧 推荐系统会根据用户画像 历史行为 如购买 喜欢 浏览等 给用户的兴趣建模
  • 36.求解简单的四则运算表达式,输入一个形式如“操作数  运算符  操作数”的四则运算表达式,输出运算结果

    36 求解简单的四则运算表达式 输入一个形式如 操作数 运算符 操作数 的四则运算表达式 输出运算结果 include
  • SpringCloud(注册中心)

    分布式架构与微服 restfu分格 入参的分格 rest分格 请求的分格 微服务 单体架构的应用场景 微服务的应用场景 上百个服务 服务于服务之间是有依赖关系的 什么是springcloud 当下流行的微服务 注册中心Eureka 注册中心
  • LeetCode-336.回文对、字典树、字符串翻转

    给定一组唯一的单词 找出所有不同 的索引对 i j 使得列表中的两个单词 words i words j 可拼接成回文串 示例 1 输入 abcd dcba lls s sssll 输出 0 1 1 0 3 2 2 4 解释 可拼接成的回文
  • N进制转十进制-C语言

    N进制到十进制 include
  • linux下eclipse集成tomcat(tomcatforEclipse)开发

    TomcatforEclipse http www eclipsetotale com 用linux 中的uzip 解压 zip 解压缩后 把解压后的文件夹放到 eclipse中的plugins中 插件特点 1 启动和停止Tomcat 4
  • IEnumerable和IEnumerator 详解

    初学C 的时候 老是被IEnumerable IEnumerator ICollection等这样的接口弄的糊里糊涂 我觉得有必要切底的弄清楚IEnumerable和IEnumerator的本质 下面我们先看IEnumerable和IEnu
  • Open3D Ransac点云球面拟合(python详细过程版)

    目录 一 算法原理 二 代码实现 三 结果展示 一 算法原理 见 1 Open3D 最小二乘拟合空间球 2 Open3D RANSAC三维点云球面拟合 二 代码实现 import open3d as o3d import numpy as
  • 快速排序(四)—— 非递归排序

    前面实现了快排的递归实现 并对其进行优化 但是递归需要在栈上为函数开辟空间 32位下 栈可使用的内存大小不超过2G 如果递归较深 依然可能会发生栈溢出 这个时候递归排序就不大适用 所以需要非递归出场 1 基础思路 1 新建一个队列 队列中存
  • 汇编程序设计与计算机体系结构,《汇编程序设计与计算机体系结构:软件工程师教程》 —3.2 基本元素...

    3 2 基本元素 与高级语言不同 汇编语言是一种底层语言 它的每一行代码只执行一项操作 要想写出汇编代码 必须了解与计算机体系结构有关的一些细节 例如 CPU 寄存器 标志位 以及浮点运算功能等 对于编程新手来说 通过这些底层细节编写汇编代
  • 【Windows】DNS优选(挑选最合适的DNS服务器)

    引言 笔者在之前的文章详解DNS服务 DNS解析 DNS劫持和污染中已经详细介绍过 DNS 了 今天给大家带来一款免费的 DNS 优选工具 仅适用 Windows 帮助大家提高上网速度 拒绝 DNS 劫持 获得更佳的上网体验 下载 官网地址
  • centos7下安装Hadoop伪分布式

    虚拟机或服务器准备 安装centos7的操作系统 安装过程请自行百度 查看是否可以通网络 使用ping 163 com 如果ping不通 可以修改网卡 一般在 etc sysconfig network scripts 的文件夹下 修改if
  • 网络安全之信息收集

    第一部分 被动信息收集 如果你对网络安全入门感兴趣 那么你需要的话可以点击这里 网络安全重磅福利 入门 进阶全套282G学习资源包免费分享 1 简介 在信息收集这块区域 我将其分为两部分 第一部分即被动信息收集 第二部分即主动信息收集 对于
  • zerotier源码编译注意事项

    1 事先安装好rust 后续编译中会用到cargo 2 切换镜像源后在make Rust使用国内Crates 源 rustup源 字节跳动新的 Rust 镜像源以及安装rust rust 国内源 西京刀客的博客 CSDN博客 3 如果是比较
  • 2022杭电多校(十)

    2022杭电多校 十 文章目录 2022杭电多校 十 一 比赛小结 二 题目分析及解法 基础题 1001 Winner Prediction 1003 Wavy Tree 1004 Average Replacement 1007 Even