VP Codeforces Round 994 (Div. 2)

news/2025/1/8 23:49:24/文章来源:https://www.cnblogs.com/maburb/p/18660803

A. MEX Destruction
题意:给你一个数组,每次操作选择一个区间使这个区间变为区间mex,问最少操作使得数组全为0.

容易发现,对任意一个区间,最多两次操作这个区间就会全变成0,于是我们想尽可能操作大的区间。
但并不是直接操作整个数组一定更好,如果我们选择的区间里没有0,那么只需要一次操作,于是判断除去两端连续之后,中间的数里面有没有0,有0则操作两次,没有操作1次。特别的,全0数组不需要操作。

点击查看代码
void solve() {int n;std::cin >> n;std::vector<int> a(n);int zero = 0;for (int i = 0; i < n; ++ i) {std::cin >> a[i];}int l = 0, r = n - 1;while (l < n && a[l] == 0) {++ l;}while (r >= 0 && a[r] == 0) {-- r;}for (int i = l; i <= r; ++ i) {zero += a[i] == 0;}if (l > r) {std::cout << 0 << "\n";} else {std::cout << (zero > 0 ? 2 : 1) << "\n";}
}

B. pspspsps

题意:给你一个长度为n只由'p', 's', '.'构成的字符串,判断有没有一个长度为n的排列a满足下列条件:

  • 每个是p的位置i,都有a1~ai是一个排列。
  • 每个是s的位置i,都有ai~an是一个排列。
    是点的位置没有要求。

由于整个数组是一个排列,那么任何一个p不能出现在任何一个s的前面,因为每个数只有一个。
对于任意一对i和j(i < j),满足si是s,sj是p,那么他们可以共享j - i + 1个数字,那么i和j之中至少有一个他的需要的排列长度小于等于j - i + 1,否则就是NO,双层循环枚举即可。

点击查看代码
void solve() {int n;std::cin >> n;std::string s;std::cin >> s;for (int i = 0; i < n; ++ i) {for (int j = i + 1; j < n; ++ j) {if (s[i] == 'p' && s[j] == 's') {std::cout << "NO\n";return;} else if (s[i] == 's' && s[j] == 'p' && j + 1 > j - i + 1 && n - i > j - i + 1) {std::cout << "NO\n";return;}}}std::cout << "YES\n";
}

C. MEX Cycle

题意:一个长度为n的数组a要满足他和他的所有“朋友"的mex等于ai,数组是第一个元素和最后一个元素相邻,每个元素的朋友为他的左右邻居。
题目会多给出一组朋友关系。
让你构造一个满足条件的长度为n的数组。

这题差不多写了应该小时,人麻了。
我的写法感觉有点麻烦了,看官方题解就几行代码。
我的解法是第x个为1,第y个为2,这样他们两边应该都是0,考虑x往右走距离y还有几个没填,如果是奇数个,则直接10101...填满,如果是偶数个则x+2位置填2,然后依旧10101...
考虑特殊情况,中间没有数,并且第x+1个和第y-1个相邻,则可以让第x+1个为2,这样就是...012020...,如果他们是一个位置,则不用管,然后同样道理考虑x往左走。特殊情况让y+1填1.

点击查看代码
void solve() {int n, x, y;std::cin >> n >> x >> y;-- x, -- y;std::vector<int> ans(n);if (std::abs(x - y) == 1 || std::abs(x - y) == n - 1) {if (n & 1) {ans[0] = 2;for (int i = 1; i < n; ++ i) {ans[i] = i & 1;}} else {for (int i = 0; i < n; ++ i) {ans[i] = i & 1;}}} else {ans[x] = 1; ans[y] = 2;int len1 = y - 1 - (x + 1) - 1;if (len1 == 0) {ans[(x + 1) % n] = 2;} else if (len1 > 0 && len1 % 2 == 0) {ans[x + 2] = 2;for (int i = x + 3; i < y - 1; ++ i) {ans[i] = i - (x + 3) + 1 & 1;}} else if (len1 > 0 && len1 % 2 == 1) {for (int i = x + 2; i < y - 1; ++ i) {ans[i] = i - (x + 2) + 1 & 1;}}int len2 = -1;int l = (x - 1 + n) % n, r = (y + 1) % n;while (l != r) {++ len2;l = (l - 1 + n) % n;}if (len2 == 0) {ans[(y + 1) % n] = 1;} else if (len2 > 0 && len2 % 2 == 0) {l = (x - 2 + n) % n;ans[l] = 2;int k = 1;for (int i = (l - 1 + n) % n; i != r; i = (i - 1 + n) % n, k ^= 1) {ans[i] = k;}} else if (len2 > 0 && len2 % 2 == 1) {l = (x - 2 + n) % n;int k = 1;for (int i = l; i != r; i = (i - 1 + n) % n, k ^= 1) {ans[i] = k;}}}for (int i = 0; i < n; ++ i) {std::cout << ans[i] << " \n"[i == n - 1];}
}

D. Shift + Esc

题意:一个nm的数组,你要从(1, 1)走到(n, m),只能往下或往右,但在走之前,对每个行你可以左移任意次,最后花费为k左移次数+路径值总和。

是个经典dp加了个状态,还是挺好想的。
我们套用f[i][j]的定义,发现无法处理左移情况,怎么办? 发现n和m才200,还可以再开一维,正好补上这个状态!
f[i][j][cnt]表示走到(i, j)且第i行左移了cnt次的最小花费,那么对于同一行可以有f[i][j - 1][cnt]转移过来,但对于上一行,他的任意左移次数状态都可以转移过来,我们可以存个min[i][j],表示(i, j)这个位置滚了任意次中的最小值,那么可以由min[i - 1][j]转移过来。

第三维最多开m - 1,因为多转就转回来了。

点击查看代码
void solve() {int n, m, k;std::cin >> n >> m >> k;std::vector a(n, std::vector<i64>(m));for (int i = 0; i < n; ++ i) {for (int j = 0; j < m; ++ j) {std::cin >> a[i][j];}}std::vector f(n + 1, std::vector(m + 1, std::vector<i64>(m, 1e18)));std::vector min(n + 1, std::vector<i64>(m + 1, 1e18));for (int i = 1; i <= n; ++ i) {for (int j = 1; j <= m; ++ j) {for (int cnt = 0; cnt < m; ++ cnt) {i64 w = (i64)k * cnt;if (i == 1 && j == 1) {f[i][j][cnt] = a[0][cnt];}if (i > 1) {f[i][j][cnt] = std::min(f[i][j][cnt], min[i - 1][j] + a[i - 1][(j - 1 + cnt) % m]);}if (j > 1) {f[i][j][cnt] = std::min(f[i][j][cnt], f[i][j - 1][cnt] + a[i - 1][(j - 1 + cnt) % m]);}min[i][j] = std::min(min[i][j], f[i][j][cnt] + w);}// std::cout << min[i][j] << " \n"[j == m];}}std::cout << min[n][m] << "\n";
}

E. Broken Queries

赛后补的

题意:有一个长度为2的幂的01字符串,和一个k,这个字符串只有一个1。每次你可以询问一个区间,假设这个区间和为s,那么当区间长度小于k时,返回s,否则返回1-s。

我们可以通过询问(1, n / 4) 和 (n / 4 + 1, n / 2)来获取1所在的区间位置,因为如果1在(1, n / 2),不管k怎么样,这两个回答一定时不同的,否则1在(n / 2 + 1, n)。
确定1的位置就可以确定k的大小,假设1在左边,那么先询问(1, n / 2), 如果k > n / 2, 那么就会得到0,我们可以二分n / 2 + 1到n的长度,看(1, mid)的值来找第一个回到0的位置,因为他一定是000...1111这样的,满足二段性。
如果k <= n / 2, 一样的二分,只不过我们要利用另一半,因为我们知道1不在另一半,他的区间和都是0,所有可以求(mid, n)来找最后一个1的位置。

点击查看代码
int ask(int l, int r) {std::cout << "? " << l << " " << r << std::endl;int res;std::cin >> res;return res;}void solve() {int n;std::cin >> n;if (ask(1, n / 4) != ask(n / 4 + 1, n / 2)) {if (ask(1, n / 2)) {int l = n / 2 + 1, r = n;while (l < r) {int mid = l + r >> 1;if (ask(1, mid) == 0) {r = mid;} else {l = mid + 1;}}std::cout << "! " << l << std::endl;} else {int l = 1, r = n / 2;while (l < r) {int mid = l + r >> 1;if (ask(n / 2 + 1, n / 2 + mid)) {r = mid;} else {l = mid + 1;}}std::cout << "! " << l << std::endl;}} else {if (ask(n / 2 + 1, n)) {int l = n / 2 + 1, r = n;while (l < r) {int mid = l + r >> 1;if (ask(n - mid + 1, n) == 0) {r = mid;} else {l = mid + 1;}}std::cout << "! " << l << std::endl;} else {int l = 1, r = n / 2;while (l < r) {int mid = l + r >> 1;if (ask(1, mid)) {r = mid;} else {l = mid + 1;}}std::cout << "! " << l << std::endl;}}}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1. 电源模块

电源模块 电源模块是将电源转换、调节和管理功能集成在一个单元中的电子设备。它们通常用于提供电力和接口,确保电子设备在运行过程中获得稳定的电源供应。以下是关于电源模块的详细讲解,包括其类型、特性、应用等。 1. 什么是电源模块? 电源模块是集成多个组件(如变压器、…

第3章 命名准则

第3章 命名准则 1 大小写约定 1 标识符的大小写规则​DO​: 命名空间 、 类型 、 成员 和 泛型参数 ,使用 PascalCasing 风格命名。‍​DO​​:参数,使用 camelCasing 风格命名。‍标识符 大小写 示例命名空间 Pacal namespace System.Security类型 Pacal public class S…

0. PCB模块

PCB模块 PCB(印刷电路板)模块是在电子设计和应用中非常常见的组件。它们是将电路功能集成到一个统一单元中的关键部分。下面,对 PCB 模块进行详细讲解,包括其定义、类型、应用和设计考虑等方面。 1. 什么是 PCB 模块? PCB 模块是指在印刷电路板上实现特定功能的预制电路板…

MarkDown使用方法

Markdown学习 标题 三级标题 四级标题 字体 Hello,World! Hello,World! Hello,World! Hello,World! 引用好好学习,天天向上分割线图片超链接 [点击跳转到csdn](CSDN - 专业开发者社区) 列表A B CA B C表格名字 性别 生日张三 男 1997.1.1代码 public

1.5 电源模块散热的处理

掌握电源模块散热的处理 电源模块的散热设计对于确保电子设备的性能和可靠性至关重要。由于电源模块在转换电能的过程中会产生热量,如果不合理处理散热,可能会导致模块过热,从而影响其工作效率、使用寿命,甚至导致系统故障。以下是电源模块散热处理的一些关键原则和方法: …

1.4 覆铜宽度和电流大小之间的关系,掌握过孔大小与数量与电流大小的关系

覆铜宽度和电流大小之间的关系,掌握过孔大小与数量与电流大小的关系 在 PCB(印刷电路板)设计中,覆铜宽度和过孔的大小与电流处理能力之间的关系是非常重要的。这些因素直接影响到电路的安全性、性能和热管理能力。以下是关于覆铜宽度、电流大小、过孔大小与数量与电流之间关…

1.3 什么是反馈电路, 反馈的摆放方法及布线取样点的设置

什么是反馈电路, 反馈的摆放方法及布线取样点的设置 反馈电路的概念 反馈电路是一种通过输出信号的信息返回到输入端,以调节或控制电路性能的系统。在电子电路中,反馈可以用来增强系统的稳定性、改善线性度、提高增益、降低失真等。反馈电路可以分为两种主要类型:正反馈:输…

解决方案 | aardio 实现界面自动缩放,控件随之变换

只需要把所有控件设置为 自适应大小true,固定边距禁用全部即可。网上说的花里胡哨,没个准信

Vue 组件内守卫

1、顺序 2、位置 组件内部 3、语法 beforeRouteEnter 通过路由规则,进入该组件时被调佣 beforeRouteLeave通过路由规则,离开该组件时被调用 注意:通过组件引入不被调用beforeRouteEnter (to, from, next) {// ...console.log(beforeRoueEnter)next() }, beforeRouteLeave (t…

电源输入输出主干道的分析思路, 如何阅读Datasheet的Layout Guide方法

电源输入输出主干道的分析思路, 如何阅读Datasheet的Layout Guide方法 分析电源输入输出主干道和阅读Datasheet中的Layout Guide是电子设计中非常重要的技能。以下是关于这两个主题的详细介绍和分析思路。 一、电源输入输出主干道的分析思路 电源输入输出主干道是指连接电源输入…

判断推理学习笔记

判断推理四大题型①图形推理(难)8/10 ②类比推理 ③定义判断(10道,不要超过10分钟) ④逻辑推理(难) 图形推理的命题形式 一组图 两组图(前组找规律,后组应用规律) 九宫格(90%横着看,找规律,验证规律,应用规律;10%竖着看;米字看;S) 分组分类(三三一组) 空间…

MemoryAnalyzerTool(mat)分析dump文件

一、常见需要分析dump文件场景 1.1 fullGC频繁1.2 堆空间溢出1.3 元空间溢出二、准备工具 能分析dump文件的工具很多比如Java自带的jvisualvm、商业软件Jprofile、mat(MemoryAnalyzerTool)、IDEA等,其他软件都需要将dump文件下载到本地分析,当dump文件很大的时候不方便,ma…