SZMS 251019 订题赛笔记

news/2025/11/22 22:36:56/文章来源:https://www.cnblogs.com/lajishift/p/19258111

串串

原题:[CEOI 2010] pin

题意

给定 \(n\) 个长度为 4 的字符串,你需要找出有多少对字符串满足恰好 \(d\) 个对应位置的字符不同。

\(n \le 5 \times 10 ^ 4, d \le 4\)

思路

前面忘了。

注意到恰好。

注意到容易钦定若干位置相同。

注意到我们学过一个东西叫做 two tasty shit reverse act。

后面忘了。

代码

#define int ll const int N = 5e4 + 5;int n, d;
string s[N];map<string, int> cnt[16];int c[5][5] = {{1, 0, 0, 0, 0},{1, 1, 0, 0, 0},{1, 2, 1, 0, 0},{1, 3, 3, 1, 0},{1, 4, 6, 4, 1}
};
void solve_test_case(){cin >> n >> d;d = 4 - d;rep(i, 1, n){cin >> s[i];}ll ans = 0;rep(i, 1, n){
//		ll res = 0;rep(S, 0, 15){string tmp = "";int popcnt = 0;per(j, 3, 0){if(S & (1 << j)){tmp = tmp + s[i][j];popcnt++;}}ans += c[popcnt][d] * ((popcnt - d) % 2 == 1 ? -1 : 1) * cnt[S][tmp];
//			cnt[popcnt][tmp]++;}rep(S, 0, 15){string tmp = "";int popcnt = 0;per(j, 3, 0){if(S & (1 << j)){tmp = tmp + s[i][j];popcnt++;}}
//			ans += c[popcnt][d] * ((popcnt - d) % 2 == 1 ? -1 : 1) * cnt[popcnt][tmp];cnt[S][tmp]++;}
//		deb(ans);}write(ans);
}

小 B 的诗集

原题:[POI 2018 R2] 诗集 Book of poetry

题意

你有一些文章,长度 \(a_i\) 行,标题占一行。你在印刷它们,每页 \(s\) 行,若标题出现在最后一行则空行翻页。求空行最小值。

\(n, s \le 10 ^ 6\)

做法

\(a_i \leftarrow (a_i + 1) \mod s\)

无法 dp,考虑贪心。

整体不好考虑,考虑局部的一步。

考虑 \(a\) 互不相同,发现到一步,如果还有至少 2 种能用的 \(a\),则必定可以不空行,否则取决于唯一选择。
贪心地选即可。

否则,我们就有重复的 \(a\),为了让以后有更多选择,我们每次保证最优策略情况下,选择剩余个数最多的就好。

代码

#define int llconst int N = 1e6 + 5;int n, s;
int a[N];
vector<int> pos[N], ans;
int sum, cnt;
priority_queue<pair<int, int>> q;
void solve_test_case(){n = read(), s = read();rep(i, 1, n){a[i] = (read() + 1) % s;pos[a[i]].push_back(i);}rep(i, 0, s - 1){if(!pos[i].empty()){q.push({pos[i].size(), i});}}rep(i, 1, n){if(sum % s == s - 1){sum = 0;cnt++;}pair<int, int> mx1 = q.top(); q.pop();if((sum + mx1.second) % s == s - 1 && !q.empty()){pair<int, int> mx2 = q.top(); q.pop();ans.push_back(pos[mx2.second].back());pos[mx2.second].pop_back();sum = (sum + mx2.second) % s;q.push(mx1);if(!pos[mx2.second].empty()) q.push({pos[mx2.second].size(), mx2.second});}else{ans.push_back(pos[mx1.second].back());pos[mx1.second].pop_back();sum = (sum + mx1.second) % s;if(!pos[mx1.second].empty()) q.push({pos[mx1.second].size(), mx1.second});}}write(cnt);for(int x : ans) write(x, ' ');
}

Journey

原题:[CERC2016] 爵士之旅 Jazz Journey

题意

黑曼巴要去 \(n\) 个城市表演肘击,他的行程是一个长为 \(d\) 的序列 \(a\)

由于黑曼巴坐飞机太久有概率遇到佐巴扬,所以他总是直飞。

黑曼巴有 \(m\) 个飞行员飞的若干航班,包括:

  • 单程票,\(u\) 单向到 \(v\)

  • 双程票,但要求必须先从 \(u\)\(v\) 以后,才可以选择\(v\)\(u\)(也就是说可以不飞)。

黑曼巴还需要留钱去【数据删除】,所以请帮他省钱。

\(n, d, m \le 3 \times 10 ^ 5\)

思路

注意到如果端点集合不同,就独立。

所以只需要考虑两个城市之间互相飞飞飞。

记录一下 \(u\)\(v\)(和反过来),\(u\)\(v\)\(u\)(和反过来)。

为了保证单程换双程一定不劣(懒得特判),并考虑双程当单程用:

u_v = min(u_v, u_v_u);
v_u = min(v_u, v_u_v);
u_v_u = min(u_v_u, u_v + v_u);
v_u_v = min(v_u_v, v_u + u_v);

不妨钦定 u_v_u \(\lt\) v_u_v,然后考虑匹配一些 u -> vv -> u
可以类比括号匹配,栈维护。
反过来,把 u -> vv -> u 的信息完全互换即可。

接着,再把 v -> uu -> v 匹配,再把剩下的花费算一下就行了。

代码

#define int llconst int N = 3e5 + 5;
const int inf = INT_MAX;int n, d;
int m;int ans = 0;struct node{int u_v, v_u;int u_v_u, v_u_v;int cnt[2];vector<int> vec;node(){cnt[0] = cnt[1] = 0;u_v = v_u = u_v_u = v_u_v = inf;vec.clear();}void ins(int t){ // t = 0 => u -> v | t = 1 => v -> ucnt[t]++;vec.push_back(t);}int calc(){if(u_v + v_u < min(u_v_u, v_u_v)){return cnt[0] * u_v + cnt[1] * v_u;}u_v = min(u_v, u_v_u);v_u = min(v_u, v_u_v);u_v_u = min(u_v_u, u_v + v_u);v_u_v = min(v_u_v, v_u + u_v);vector<int> stk;if(u_v_u > v_u_v){for(int &x : vec){x = 1 - x;}swap(u_v, v_u);}int res = 0;for(int x : vec){if(!stk.empty() && x == 1 && stk.back() == 0){stk.pop_back();res += min(u_v_u, v_u_v);}else{stk.push_back(x); }}vector<int> stk2;for(int x : stk){if(!stk2.empty() && x == 0 && stk2.back() == 1){stk2.pop_back();res += max(u_v_u, v_u_v);}else{stk2.push_back(x);}}for(int x : stk2){if(x == 0) res += u_v;else res += v_u;}return res;}
};
map<pair<int, int>, node> mp;
int a[N];pair<int, int> key(int x, int y){return make_pair(min(x, y), max(x, y));
}vector<pair<int, int>> used;void solve_test_case(){n = read(), d = read();rep(i, 1, d){a[i] = read();}m = read();rep(i, 1, m){int u = read(), v = read();char c = read_c();int w = read();used.push_back(key(u, v));if(c == 'O'){if(u < v) mp[key(u, v)].u_v = min(mp[key(u, v)].u_v, w);if(u > v) mp[key(u, v)].v_u = min(mp[key(u, v)].v_u, w);}else{if(u < v) mp[key(u, v)].u_v_u = min(mp[key(u, v)].u_v_u, w);if(u > v) mp[key(u, v)].v_u_v = min(mp[key(u, v)].v_u_v, w);}}rep(i, 1, d - 1){used.push_back(key(a[i], a[i + 1]));mp[key(a[i], a[i + 1])].ins((a[i] < a[i + 1]) ? 0 : 1);}sort(used.begin(), used.end());used.erase(unique(used.begin(), used.end()), used.end());for(pair<int, int> id : used){ans += mp[id].calc();}write(ans);
}

Photo

原题:[JOI 2021 Final] 集体照 / Group Photo

题意

给你一个序列 \(a\),可以邻项交换,使得 \(a_i - a_{i + 1} \ge -1\),求最小交换次数。

\(|a| = n \le 5000\)

思路

容易发现,最后 \(a\) 要变成形如:

的若干公差为 -1 的数列拼起来。

发现不好直接算这个图形的答案,考虑 dp。
考虑 dp 的转移顺序,下标从小到大状态数显然不对,于是考虑按照值域做 dp。
\(dp_i\) 表示把值域 \([1,i]\) 的排到下标 \([1,i]\) 上,保证 \(i\) 是一个等差数列的结尾,此时的最小次数。

转移顺序应当是 \(dp_i \rightarrow dp_j\)

我们需要计算将区间 \([i+1,j]\) 排好的代价,注意到直接算不好算,那么我们可以利用递推的思想,把 \([i+1, j- 1]\) 的代价递推到 \([i + 1, j]\) 上。

image

相当于加上 \(j\) 从右边飞到 \(i + 1\) 左边的贡献。

分析这个过程,若一个 \([i + 1, n]\) 中的数在开始的时候是在 \(j\) 左侧,现在 \(j\) 飞过来就变成 \(j\) 的右侧,根据冒泡排序理论应当造成 1 的贡献。
类比冒泡排序理论,定义逆序对 \((x,y)\) 为原序列 \(x\)\(y\) 左侧,新序列 \(x\)\(y\) 右侧。
则此处新产生的代价即为 \(\sum \limits _{i + 1 \le p \le n} [(p, j) 是逆序对]\)

那么相反的,\(j\) 的移动会使得一些逆序对消失,具体地,是 \(j\)\(p, i + 1 \le p \le j - 1\) 构成逆序对,现在 \(j\) 不在 \(p\) 右侧而摧毁了它。

维护区间和单点构成逆序对个数(第二类可以交换 \(x\)\(y\),转换为统计顺序对个数,进而转换为统计逆序对个数)即可,简单前缀和实现。

那么我们就能递推算出 \([i + 1,j]\) 的代价,进而实现转移。

复杂度 \(O(n ^ 2)\)

代码

#define int llconst int N = 5010;int n;
int a[N];
int pos[N];
int cnt1[N][N], cnt2[N][N];
int f[N];void solve_test_case(){n = read();rep(i, 1, n){a[i] = read();pos[a[i]] = i;}rep(i, 1, n){rep(j, 1, n){cnt1[i][j] = cnt1[i - 1][j] + (pos[i] > pos[j]);}}rep(i, 1, n){rep(j, 1, n){cnt2[i][j] = cnt2[i - 1][j] + (pos[i] < pos[j]);}}memset(f, 0x3f, sizeof(f));f[0] = 0;rep(i, 0, n - 1){int res = 0;rep(j, i + 1, n){res -= (cnt1[j - 1][j] - cnt1[i][j]);res += (cnt2[n][j] - cnt2[i][j]);f[j] = min(f[j], f[i] + res);}}write(f[n]);
}

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

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

相关文章

关于面向对象程序设计的第一阶段大作业总结

一、前言 本次三次题目集聚焦 “单部电梯调度系统”,是面向对象编程的迭代式实践。涉及的知识点包括 Java 类与对象、枚举封装、集合框架(LinkedList)、单一职责原则(SRP)、电梯调度算法及输入校验。但对我而言,…

Spring Boot核心知识点全解析 - 实践

Spring Boot核心知识点全解析 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monac…

RHCA - DO374 | Day03:通过自动化控制器运行剧本 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

离职/毕业-清理电脑

这段内容主要面向打工人,强调离职前清理电脑个人信息、保护隐私的重要性,并详细介绍了从微信聊天记录、电脑使用记录、上网记录、软件缓存四个方面一键清理个人信息的方法。开篇指出离职小白常误以为卸载软件就能清理…

2025.11.22

今天学习vue的项目布局,明天继续学习布局,然后就要开始前后端连接了

在 Python 和 NumPy 的常规书写规范中,ndarray需要大写吗?

在 Python 和 NumPy 的常规书写规范中,ndarray 通常使用小写,不需要大写。 ✅ 正确用法:ndarray(小写) 官方文档、NumPy 源码和社区惯例中,ndarray 始终是小写的。 它是 NumPy 中一个类的名称(numpy.ndarray),…

ddddocr: 对图片处理提升识别率

一,识别有误 dataurl: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPAAAABQCAMAAAAQlwhOAAAA81BMVEUAAAB/TiCdbD6GVSdoNwnPnnB7ShyDUiTDkmR5SBrVpHbMm22FVCa5iFrUo3WUYzW9jF5yQRPDkmS/jmCFVCZyQRNnNghvPhCVZDZfL…

`np.array` 和 `np.ndarray`是什么关系?

np.array 和 np.ndarray 是 NumPy 中两个密切相关但用途和行为完全不同的概念。理解它们的关系是掌握 NumPy 的关键之一。🔹 1. np.ndarray:NumPy 数组的底层类(类型)numpy.ndarray 是 所有 NumPy 数组对象的实际…

大数据部门和AI部门边界

目录背景和价值1. 大数据部门的职责 (Big Data Department - 平台建设方)2. AI部门的职责 (AI Department - 价值应用方)总结:技术总监的战略划分参考资料 背景和价值 这是一个在组织架构中非常关键的问题,也是检验技…

Post Processing

Post Processing后处理 Unity Grab URP Render Feature Godot screen_texture Godot 面片法

工作草稿

自行车产业链发展的三种模式 一、加工增值模式进口高端碳纤维(德国织布机) 17%关税车架、车把 8%关税 → 增值 50%高端自行车日本禧玛诺车零件关税 20% 增值 30% 国内销往鱼杆、船桨、高尔夫 (昆山、吉林、呼和浩特…

【Rust编程:从新手到大师】Rust 环境搭建(详细版) - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

OOP第一到三次作业总结 -单部电梯调度

一、前言 博主近期疏于学业,故而三次作业均没有完整实现出来,因此这是一篇反思文,同博主一样起步浑浑不清者,可借此文规避一些低效的思路。 (博主依赖ai成瘾,借主播血泪教训,建议读者切忌一味信赖ai!应当试着自…

2025年11月南通宠物医疗市场深度分析:专业服务与行业规范的标杆选择

在宠物经济快速发展的浪潮中,宠物医疗行业正经历从"基础服务"向"专业医疗"的深刻转型。据最新行业报告显示,南通地区宠物医疗市场规模年均增长达16.8%,宠物主人对医疗服务的期望已从"能看…

用户亲测!用 DiffMind 用 AI,省一半时间还出效果,小白也能轻松上手

用户亲测!用 DiffMind 用 AI,省一半时间还出效果,小白也能轻松上手“用 AI 写文案要切 3 个平台,改简历改 5 遍还不对,查个信息怕 AI 瞎编”—— 如果你也有这些糟心经历,那一定要试试DiffMind(官网www.diffmin…

软工团队作业3

作业信息这个作业属于哪个课程 首页 - 计科23级34班 - 广东工业大学 - 班级博客 - 博客园这个作业要求在哪里 团队作业3--需求改进&系统设计 - 作业 - 计科23级34班 - 班级博客 - 博客园这个作业的目标 明确团队项…

电梯调度迭代编程作业复盘

一、对三次电梯调度题目集的整体认知 (一)知识点覆盖与考察重点 三次电梯调度题目集聚焦面向对象编程核心知识点与工程化开发能力,核心考察内容可归纳为三类: 设计原则:核心是单一职责原则。从第一次的 “单类包揽…

球坐标系的大运动方程组

球坐标系的大运动方程组P=P(λ, φ, r) 其中,λ——经度φ——纬度r——地心到空间点的距离

【数据库】navicat的下载以及数据库约束 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

i2c linux

您提到的 "i2c linux" 可能是指与 I2C(I2C)总线 相关的 Linux 系统操作。I2C 是一种常用的串行通信协议,用于连接微控制器、传感器、EEPROM、Flash 存储器等设备。在 Linux 系统中,I2C 通常通过 i2c-dev…