当前位置: 首页 > news >正文

JSCPC 2025 江苏省赛

D. Spell Generation

题目大意

有一个按钮,按住2x2^x2x秒可以得到10x10^x10x的值,现在要得到数字n,问至少要按住多少秒

解题思路

按题意模拟即可

代码实现

#include <bits/stdc++.h>using i64 = long long;int main() {std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);int tt;std::cin >> tt;while (tt--) {std::string s;std::cin >> s;std::reverse(s.begin(), s.end());i64 ans = 0;for (int i = 0; i < s.size(); i++) {ans += (s[i] - '0') * (1 << i);}std::cout << ans << "\n";}
}

F. Ranking Prediction

题目大意

给定某个队伍的比赛提交信息,问这个队伍封榜后至少过几题才能超过你们队,不可能超过则输出-1

解题思路

按题意模拟即可

代码实现

#include <bits/stdc++.h>using i64 = long long;int main() {std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);int tt;std::cin >> tt;while (tt--) {int n, a, b, s, penalty = 0;std::cin >> n >> a >> b >> s;std::map<std::string, int> ac, pd1;std::vector<std::tuple<std::string, int>> rj;for (int i = 0; i < s; i++) {int t;std::string p, v;std::cin >> t >> p >> v;if (v == "ac") {if (ac.count(p)) {ac[p] = std::min(ac[p], t);} else {ac[p] = t;}} else if (v == "pd" && !ac.count(p)) {if (pd1.count(p)) {pd1[p] = std::min(pd1[p], t);} else {pd1[p] = t;}} else {rj.push_back({p, t});}}std::map<std::string, int> rj_cnt;for (auto [p, t] : rj) {if (ac.count(p) && ac[p] > t) {rj_cnt[p]++;}if (!ac.count(p) && pd1.count(p) && pd1[p] > t) {rj_cnt[p]++;}}for (auto [p, t] : ac) {penalty += t + 20 * rj_cnt[p];}for (auto &[p, t] : pd1) {t += 20 * rj_cnt[p];}std::vector<std::tuple<int, std::string>> pd2;for (auto [p, t] : pd1) {pd2.push_back({t, p});}std::sort(pd2.begin(), pd2.end());if (ac.size() > a || ac.size() == a && penalty < b) {std::cout << 0 << "\n";} else {int f = 1, cnt = ac.size();for (auto [t, p] : pd2) {penalty += t;cnt++;if (cnt > a || cnt == a && penalty < b) {std::cout << cnt - ac.size() << "\n";f = 0;break;}}if (f) {std::cout << -1 << "\n";}}}
}

J. Puzzle Competition

题目大意

给定一张n点m边有向图,每个节点都有点权,边都有边权,一开始所有节点和边都是锁定的,只有被激活的入边数量不少于点权时才能激活该节点,如果一个节点被激活,其所有的出边经过边权时间后会被激活,有一些特殊装置会在指定时间后激活指定节点,问某个节点被激活的最小时间,不可能则输出-1

解题思路

参考拓扑序,对于被激活的边都向连接的点输送1的能量,装置可以看做在指定时间后指定节点有无穷大的能量,优先队列维护即可

代码实现

#include <bits/stdc++.h>using i64 = long long;
const i64 INF = 4e18 + 10;int main() {std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);int n, m, k;std::cin >> n >> m >> k;std::priority_queue<std::array<i64, 3>, std::vector<std::array<i64, 3>>, std::greater<std::array<i64, 3>>> pq;std::vector<std::array<i64, 2>> ans(n + 1, {INF, 0});for (int i = 1; i <= n; i++) {std::cin >> ans[i][1];if (ans[i][1] == 0) {pq.push({0, i, INF});}}for (int i = 0; i < k; i++) {int t, sc;std::cin >> t >> sc;for (int j = 0; j < sc; j++) {int id;std::cin >> id;pq.push({t, id, INF});}}std::vector<std::vector<std::array<i64, 2>>> g(n + 1, std::vector<std::array<i64, 2>>());for (int i = 0; i < m; i++) {i64 u, v, w;std::cin >> u >> v >> w;g[u].push_back({v, w});}std::vector<int> vis(n + 1);while (!pq.empty()) {auto [t, u, x] = pq.top();pq.pop();if (vis[u]) {continue;}ans[u][1] -= x;if (ans[u][1] <= 0) {vis[u] = 1;ans[u][0] = t;for (auto [v, w] : g[u]) {if (!vis[v]) {pq.push({t + w, v, 1});}}}}for (int i = 1; i <= n; i++) {if (ans[i][0] == INF) {std::cout << -1 << " \n"[i == n];} else {std::cout << ans[i][0] << " \n"[i == n];}}
}

G. Monetary System

题目大意

给定n张不同面额的货币,在选取面额尽可能大的情况下,问用m张货币能凑出多少种不一样的总金额

解题思路

已经给出f(x,y)的递推式,直接二分当前可用最大面额+记忆化搜索处理出f[i],之后再用前缀和来维护不超过x的金额能有多少种方案

代码实现

#include <bits/stdc++.h>using i64 = long long;
const int N = 1e6 + 10;
const i64 INF = 4e18 + 10;int main() {std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);int n, q;std::cin >> n >> q;std::vector<i64> a(n + 2), b(N), f(N);for (int i = 1; i <= n; i++) {std::cin >> a[i];}a[n + 1] = INF;auto dfs = [&](auto &&self, int x, int y) -> i64 {if (x == 0) {return 0;} else if (y == 1) {return x;} else if (f[x]) {return f[x];} else {return x / a[y] + self(self, x % a[y], y - 1);}};for (int i = 1; i <= a[n]; i++) {f[i] = dfs(dfs, i, std::upper_bound(a.begin(), a.end(), i) - a.begin() - 1);b[f[i]]++;}for (int i = 1; i <= a[n]; i++) {b[i] += b[i - 1];}for (int i = 1; i <= q; i++) {i64 x;std::cin >> x;std::cout << b[std::min(x, a[n])] << " \n"[i == q];}
}

H. Loose Subsequences

题目大意

对经典的本质不同的子序列加上一个新的约束,子序列字母的间隔必须要相隔k以上,求这个条件下本质不同的子序列有多少,对答案模998244353

解题思路

k=0时是一个经典的不同本质子序列问题,可以用前缀和来维护,减掉重复贡献,不为0的时候对于上次出现的位置以及前缀和需要再往前k个

代码实现

#include <bits/stdc++.h>using i64 = long long;
const int MOD = 998244353;int main() {std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);int tt;std::cin >> tt;while (tt--) {int n, k;std::cin >> n >> k;std::string s;std::cin >> s;s = " " + s;std::vector<i64> dp(n + 1), pre(n + 1);dp[0] = pre[0] = 1;std::map<char, int> last;for (int i = 1; i <= n; i++) {dp[i] = pre[std::max(i - k - 1, 0)];if (last.count(s[i])) {dp[i] = (dp[i] - pre[std::max(last[s[i]] - k - 1, 0)] + MOD) % MOD;}pre[i] = (pre[i - 1] + dp[i]) % MOD;last[s[i]] = i;}std::cout << (pre[n] - 1 + MOD) % MOD << "\n";}
}

I. Team Naming

题目大意

n个名字为三个字的人,问有多少三人队使得每个人名选一个不同位置的字组成的名字是队里的一个人名

解题思路

容斥+统计,详见注释

代码实现

#include <bits/stdc++.h>using i64 = long long;int main() {std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);int n;std::cin >> n;std::vector<std::array<int, 3>> s(n);std::map<int, int> mp0, mp1, mp2;std::map<std::array<int, 2>, int> mp01, mp02, mp12;for (int i = 0; i < n; i++) {std::cin >> s[i][0] >> s[i][1] >> s[i][2];mp0[s[i][0]]++;mp1[s[i][1]]++;mp2[s[i][2]]++;mp01[{s[i][0], s[i][1]}]++;mp02[{s[i][0], s[i][2]}]++;mp12[{s[i][1], s[i][2]}]++;}i64 ans = 0;for (int i = 0; i < n; i++) {                                                                                        // 每次都匹配第i个人的名字int s0 = mp0[s[i][0]] - 1, s1 = mp1[s[i][1]] - 1, s2 = mp2[s[i][2]] - 1;                                         // 在0,1,2位置能匹配上的人int s01 = mp01[{s[i][0], s[i][1]}] - 1, s02 = mp02[{s[i][0], s[i][2]}] - 1, s12 = mp12[{s[i][1], s[i][2]}] - 1;  // 在01,02,12位置能匹配上的人int x = s0 - s01 - s02, y = s1 - s01 - s12, z = s2 - s02 - s12;                                                  // 只在0,1,2位置能匹配上的人ans += x * y + x * z + y * z;                                            // jk只在一个位置上做贡献ans += (s01 + s02 + s12) * (x + y + z);                                  // jk其中一人在两个位置做贡献,另一人在一个位置做贡献ans += s01 * s02 + s01 * s12 + s02 * s12;                                // jk都在两个位置上做贡献,但是贡献的位置不同ans += s01 * (s01 - 1) / 2 + s02 * (s02 - 1) / 2 + s12 * (s12 - 1) / 2;  // jk都在两个位置上做贡献,但是贡献的位置相同}std::cout << ans << "\n";
}
http://www.dtcms.com/a/279958.html

相关文章:

  • VictoriaMetrics 架构
  • 位置编码类型彩色图解
  • 考虑频率耦合的构网型(GFM)VSG变流器(电压电流双闭环控制结构)的二维序阻抗与降维SISO序阻抗建模详细推导及扫频对比验证
  • 【人工智能99问】什么是深度学习?(2/99)
  • Kimi K2智能体能力的技术突破:大规模数据合成 + 通用强化学习
  • 名片管理系统IV
  • 螺旋模型:风险分析驱动的渐进式开发
  • cuda优化之softmax
  • 组件化思想
  • Brooks 低温泵On-Board Cryopump 安装和维护手法Installation and Maintenance Manual
  • aspnetcore Mvc配置选项中的ModelBindingMessageProvider
  • 第二章 基于新版Onenet搭建云服务(stm32物联网)
  • PyTorch中torch.topk()详解:快速获取最大值索引
  • @Resource 注解的空值处理(默认行为与容器实现)
  • 冲刺阶段项目进度压力大,如何组织高效冲刺
  • 大屏搭建多个图表不自适应问题
  • H264编码结构和解析
  • 第四章 uniapp实现兼容多端的树状族谱关系图,剩余组件
  • ESP32 OTA升级详解:使用Arduino OTA库实现无线固件更新
  • HTML 文本格式化标签
  • java--ThreadLocal创建以及get源码解析
  • http常见状态码
  • 苦练Python第18天:Python异常处理锦囊
  • 【论文阅读】Masked Autoencoders Are Effective Tokenizers for Diffusion Models
  • rsyslog简单应用
  • STM32F769I-DISCO 串口调试
  • Linux上基于C/C++头文件查找对应的依赖开发库
  • SAP B1认证资料-题目
  • 分布式系统中实现临时节点授权的高可用性与一致性
  • 哈希扩展 --- 海量数据处理