1.7 CW 模拟赛 赛时记录

news/2025/1/8 16:44:33/文章来源:https://www.cnblogs.com/YzaCsp/p/18657550

前言

这次没复习直接上, 无敌了

还是策略 + 时间分配, 好好考

看题

大样例发的有点神经的

\(\rm{T1}\)

什么数数题, 红温了, 不太看得出来的样子

\(\rm{T2}\)

有点神秘

\(\rm{T3}\)

又是数数, 无语了

\(\rm{T4}\)

神秘


首先应该是普通难度, 打不了的题先跳过, 先拿暴力分, 不要死磕

\(\rm{T1}\)

思路

作为一个刚学了一堆数数 \(\rm{trick}\) 的人, 看看能不能冲一下正解

转化题意

对于一个 \(n\)\(m\) 列的 \(01\) 矩阵, 求有多少种行数的集合, 使得翻转这些行以后每一列至多有一个 \(1\)

\(60 \%\) 给状压, 好像还不是很稳

通过简单转化我们可以知道, 对于 \(m\) 列, 有哪些集合及集合的反转会使这一位有 \(1\), 记为 \(\mathbb{U}\)
考虑正难则反算至少有一列至少有两个 \(1\) 的情况, 也就是说, 我们随意挑选至少一列的 \(\mathbb{U}\) 中的两个集合 (不能是一个集合和其反转不能同时选择) , 就可以产生一种非法情况

考虑非法情况的计数


好吧时间不够了, 先考虑暴力, 最后有时间再想正解

对于 \(20 \%\) , 先处理选择的行的集合, 然后 \(\mathcal{O} (nm)\) \(\rm{check}\) 即可, 总时间复杂度 \(\mathcal{O} (2^n nm)\)

对于 \(40 \%\) , 我们考虑状压 \(\rm{dp}\)
\(f_{i, \mathbb{S}}\) 表示考虑了前 \(i\) 行, 当前的放 \(1\) 情况为 \(\mathbb{S}\) 时的方案数
考虑转移, 记 \(s_i\) 表示第 \(i\) 行不反转时 \(1\) 的位置集合, \(s^{\prime}_i\) 表示第 \(i\) 行反转时 \(1\) 的位置集合

\[\begin{align*} \forall \mathbb{S} \cap s_i = \varnothing , f_{i - 1, \mathbb{S}} \to f_{i, \mathbb{S} \cup s_i} \\ \forall \mathbb{S} \cap s^\prime_i = \varnothing , f_{i - 1, \mathbb{S}} \to f_{i, \mathbb{S} \cup s^\prime_i} \end{align*} \]

总时间复杂度 \(\mathcal{O} (n 2^m)\)

实现

框架

实现两个部分

  • \(n\) 较小时
    暴力模拟即可
  • \(m\) 较小时
    如上状压 \(\rm{dp}\) 即可

代码

/*对于 n 较小时的做法*/
class subtask1
{
private:bool chose[MAXN];bool check(int S) {int cnt = 0;for (int i = 1; i <= n; i++) chose[i] = (S >> (i - 1)) & 1;for (int i = 1; i <= m; i++) {int res = 0;for (int j = 1; j <= n; j++) {if (chose[j]) res += (mat[j][m - i + 1] == '1');else res += (mat[j][i] == '1');}if (res > 1) return false;}return true;}public:void solve() {int ans = 0;for (int S = 0; S < (1 << n); S++) // 外层枚举选行的状态if (check(S)) ans++;printf("%lld\n", ans);}
} sub1;/*对于 m 较小时的做法*/
class subtask2
{
private:int f[2][MAXVAL];int s1[MAXN], s2[MAXN];/*预处理 s_i, s'_i*/void init() {for (int i = 1; i <= n; i++) {s1[i] = s2[i] = 0;for (int j = 1; j <= m; j++) {if (mat[i][j] == '1') s1[i] += (1 << (j - 1));if (mat[i][m - j + 1] == '1') s2[i] += (1 << (j - 1));}}}public:void solve() {init();int now = 0, nxt = 1;memset(f, 0, sizeof(f)); f[now][0] = 1;for (int i = 0; i < n; i++) {memset(f[nxt], 0, sizeof(f[nxt]));for (int S = 0; S < (1 << m); S++) {if (!(S & s1[i + 1])) f[nxt][S | s1[i + 1]] += f[now][S];if (!(S & s2[i + 1])) f[nxt][S | s2[i + 1]] += f[now][S];}std::swap(now, nxt);}int ans = 0;for (int S = 0; S < (1 << m); S++) ans += f[now][S];printf("%lld\n", ans);}
} sub2;

\(\rm{T2}\)

目前得分: \(60 \ \rm{pts}\)

思路

不是数数, 加油冲冲冲

看到这个形式就想转差分, 不管怎么样先用这个思路转化题意

给定一个序列 \(a\) , 每次操作你可以任取 \(i \in [1, n]\) , 将 \(a_i + 1, a_{i + 1} - 1\) 或者将 \(a_i - 1, a_{i + 1} + 1\) , 求至多 \(k\) 此操作后, 最长的连续 \(1\) 有多长 ( \(a_1, a_{n + 1}\) 不计入统计)

你发现 \(k\) 很大, 也属于一种提醒, 不能一次一次模拟

\(666\) , 根本不会做

实现

考虑 \(10 \%\)

#include <bits/stdc++.h>
const int MAXN = 1e5 + 20;
int T;
int n, k, a[MAXN], dif[MAXN];int main()
{scanf("%d", &T);while (T--) {scanf("%d %d", &n, &k);for (int i = 1; i <= n; i++) scanf("%d", &a[i]), dif[i] = a[i] - a[i - 1];int ans = 0;int res = 0;for (int i = 2; i <= n; i++) {if (dif[i] == 1) { res++; ans = std::max(res, ans); }else res = 0;}printf("%d\n", ans + 1);}return 0;
}

\(\rm{T4}\)

目前得分: \(70 \ \rm{pts}\)

思路

这题能骗多少骗多少

\(30 \%\) 给了暴力模拟, 维护每个串串当前的首位, 然后暴力计算即可
考虑 \(n = 2\) , 暴力枚举会 \(\rm{TLE}\) , 怎么做
考虑 \(l_i \leq 2\) , 暴力枚举会 \(\rm{TLE}\) , 怎么做

急急急, 把 \(30 \%\) 打完去冲 \(\rm{T3}\)\(\mathcal{O} (nk)\)

实现

框架

模拟模拟

代码

#include <bits/stdc++.h>
const int MAXN = 6;
const int MAXL = 6;
#define lcm(a, b) a / std::__gcd(a, b) * bint T;
int n, m;
int a[MAXN][MAXL];
int l[MAXN];int main()
{scanf("%d", &T);while (T--) {scanf("%d %d", &n, &m);int times = 1;for (int i = 1; i <= n; i++) {scanf("%d", &l[i]); times = lcm(times, l[i]);for (int j = 1; j <= l[i]; j++) scanf("%d", &a[i][j]);}for (int i = 1; i <= m; i++) {int ans = 0;int head[MAXN];memset(head, 0, sizeof(head));for (int j = 1; j <= times; j++) {for (int k = 1; k <= n; k++) head[k] = ((head[k] + 1) > l[k] ? 1 : head[k] + 1);int res = 0;for (int k = 1; k <= n; k++) {if (a[k][head[k]] == i) { res++; ans = std::max(ans, res); }else res = 0;}}printf("%d ", ans);}printf("\n");}return 0;
}

\(\rm{T3}\)

目前得分: \(100 \ \rm{pts}\)

思路

现在优势一点都不在我, 主要是 \(\rm{T2}\) 基本上啥都不会, 寄!

又是数数, 看看这题够不够典

转化题意

给定一棵 \(n\) 节点的树, 求删边边集的数量, 使得剩余部分的连通块大小均为 \(k\) 或者 \(k + 1\)

怎么又是和 \(\rm{T1}\) 很像的形式, 不是哥们
不过这个题像树形 \(\rm{dp}\)


好吧也是再次没想出来

考虑 \(10 \%\) 直接状态压缩之后 \(\mathcal{O} (n)\) \(\rm{check}\)

还有个链的 \(10 \%\) 考虑动态规划
具体的, 令 \(f_{u, s}\) 表示对于 \(u\) 这个点, 其带了一个大小为 \(s\) 的连续块过来的方案数
初始化 \(f_{leave, 1} = 1\)
考虑转移 (假设 \(u\) 的下一个点为 \(v\) )

\[\begin{align*} & f_{u, 1} \gets f_{v, k} + f_{v, k + 1} \\ & f_{u, s} \gets f_{v, s - 1} \end{align*} \]

然后发现数组开不下? 直接打完 \(10 \%\) 跑路, 不过这个好像可以拓展成 \(60 \%\)

不过问题是 \(\rm{T4}\) 部分分很足, 先开 \(\rm{T4}\) , 这 \(10 \%\) 留到后面, 还有时间就把 \(60 \%\) 打了


好好好, 剩余的时间全部冲这题的 \(\mathcal{O} (nk)\) , 先手模一遍确定正确性
我样例呢?!

好好好, 正确性没问题, 但转移方式还要细想

考虑对于 \(u\) 子树及其儿子 \(son(u)\) , 怎么转移
容易发现的是我们可以一颗子树一颗子树的加入, 不影响答案
考虑对于 \(f_{u, i}\) , 会从哪些 \(v\) 的地方产生贡献
怎么怎么搞都是 \(\mathcal{O} (n k^2)\) 的, 红温了
考虑类似树上背包的形式, 还是只能到 \(\mathcal{O} (n k^2)\)

实现

只能打个暴力了

#include <bits/stdc++.h>
const int MAXN = 21;
const int MOD = 998244353;int n, k;
struct node {int to, next;
} edge[MAXN << 1];
int cnt = 0, head[MAXN];
void init() {cnt = 0;for (int i = 1; i <= n; i++) head[i] = -1;
}void addedge(int u, int v) {edge[++cnt].to = v, edge[cnt].next = head[u];head[u] = cnt;
}int sz;
bool canuse[MAXN << 1];
bool vis[MAXN];
void dfs(int now) {sz++;vis[now] = true;for (int i = head[now]; ~i; i = edge[i].next) {int nowto = edge[i].to;if (vis[nowto] || !canuse[i]) continue;dfs(nowto);}
}bool check(int s) {memset(canuse, false, sizeof(canuse)); memset(vis, false, sizeof(vis));int ret = 0;while (s) {ret++;if (s & 1) {canuse[ret] = canuse[ret + 1] = true;} else {canuse[ret] = canuse[ret + 1] = false;}ret++;s >>= 1;}for (int i = 1; i <= n; i++) {sz = 0;if (!vis[i]) dfs(i);if (sz != k + 1 && sz != k && sz) return false;}return true;
}int main()
{int T; scanf("%d", &T);while (T--) {scanf("%d %d", &n, &k);init();for (int i = 1; i < n; i++) {int u, v;scanf("%d %d", &u, &v);addedge(u, v), addedge(v, u);}int ans = 0;for (int i = 0; i < (1 << (n - 1)); i++) {if (check(i)) ans = (ans + 1) % MOD;}printf("%d\n", ans);}return 0;
}

后记

\(\rm{qtmd}\) , 破大防

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

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

相关文章

.net6之阿里云OSS

概念 集成阿里云OSS文件存储服务 引用阿里云包封装AliyunSmsClient(二次封装阿里云短信基类)public class AliyunOssClient{private readonly AliyunOssOptions _options;private readonly OssClient _client;public AliyunOssClient(IOptions<AliyunOssOptions> options…

React数值滚动效果,支持数值变化变化

效果:组件:(NumberScroller.jsx)/*** 数字滚动效果*/ import React, { useEffect, useState } from react; import PropTypes from prop-types;const NumberScroller = ({ targetValue = 0, decimalPlaces = 0, duration = 2000 }) => {const [value, setValue] = useSt…

C#笔记(1、钉钉机器人推送帆软报表图片)

C#笔记——钉钉机器人推送帆软报表图片(一)1、前言 ​ 2024年最后一个月,家里多了个小公主,在家休息了一段时间。2025年,休完假上班第一天,领导就说:哎,我看总部那边做了个每日产出的报表推送到钉钉群,来看计划达成率。我们基地这边能不能做啊。我心里默默一想,然后大…

Javascript实现asp.net mvc的checkbox基本功能

Html的checkbox使用很广的,它的状态,勾选与非选。初始状态,默认为非选。你可以设置它是勾选, 直在checkbox 标签中,添加checked属性。另外,在javascript可以这样,getById(Checkbox_IsPublished).checked = true; 或者,getById(Checkbox_IsPublished).setAttribute(che…

“非旺玖原装的PL2303,请联系您的供应商”232串口转换器解决办法

偶尔会用到PL2303这种十几年前的旧芯片做的232串口转换器,如果手头没有别的工具必须使用的话,需要配置一下才能使用。该串口调试器在不同的USB口插入可能出现COM口无效或者端口号变动(COM 4/7/8等),需要通过设备管理器进行修改 当提示题目上的错误时,需要重装旧版本驱动1…

记录一个Github推送的问题(ssh推送出现:Connection closed by 198.18.0.9 port 22)

一、前言: 在公司需要将一个文档推送到GitHub仓库,由于Github对Https的推送已经移除了对密码认证的支持(2021.8.13),所以想要进行身份验证就只能使用两种方式:使用Persional Access Token(PAT) 使用SSH认证 PAT认证太麻烦了,每次都要输入,这里就主要介绍使用SSH认证的方…

安川机器人的独特优势

安川机器人,这一源自日本安川电机(Yaskawa Electric Corporation)的杰出产物,是工业自动化领域中的佼佼者,其核心价值在于生产线上那精准无误的自动化作业能力。这款机器人集成了电机、减速器、传感器、控制器等一系列精密部件,如同一套高效协同的作战系统,为企业带来了生…

2020-2024 IDEA安装+激活

一、下载 1. IDEA各版本官方下载入口 IDEA官网下载地址 2. 选择左边,然后点击【20xx.x.x-Windows(exe)】 PS: 如需下载特定版本,可以往下拉,都是选择【202x.x-Windows(exe)】下载二、安装 1. 点击运行 ps: 安全警告是部分电脑有,没有跳过就可以了~2. 点击下一步3. 选择安…

CDS标准视图:维护包描述 I_MaintPackageTextData

视图名称:维护包描述 I_MaintPackageTextData 视图类型:基础 视图代码:点击查看代码 @EndUserText.label: Maintenance Package - Text @ObjectModel.dataCategory: #TEXT @VDM.viewType: #COMPOSITE @AbapCatalog.sqlViewName: IMNTPCKGTXTDATA @AbapCatalog.compiler.comp…

CDS标准视图:维护包数据 I_MaintenancePackageData

视图名称:维护包数据 I_MaintenancePackageData 视图类型:基础 视图代码:点击查看代码 @AbapCatalog.sqlViewName: IMAINTPCKGDATA @AbapCatalog.compiler.compareFilter: true @AccessControl.authorizationCheck: #PRIVILEGED_ONLY @EndUserText.label: Maintenance Packa…

让跨 project 联查更轻松,SLS StoreView 查询和分析实践

在业务场景中,日志数据可能存储在日志服务 Project 的不同 Logstore/MetricStore 中或不同地域的 Project 中。日志服务的数据集(StoreView)功能支持跨地域、跨 Store 联合查询和分析,让用户基于数据集就能高效便捷地查询分析全地域的数据,真正做到数据分析不受地域边界的…

流程配置中心同步后流程版本ID不一致

不同的账套进行流程发布时会产生不同的版本ID , BOS同步后的流程设计的ID是相同的.