2024 CCPC 郑州题解 (gym105158)

news/2025/3/6 20:54:31/文章来源:https://www.cnblogs.com/Young-Cloud/p/18756436

A

其实是构造。

构造出 123456789d000……。 后面 0 的个数跟给定 n 的位数相同。

然后加上 n 减模数就好了

CODE
void solve() {int n,d;cin>>n>>d;i64 cur=1234567890ll+d;int nn=n;while(nn){cur=cur*10;nn=nn/10;}i64 k=cur%n;k=n-k;cur+=k;i64 ans=cur/n;cout<<ans<<'\n';
}

B

贪心,对于每轮,将买过的所有比当前轮贵的(用优先队列维护)都放弃掉来买当前轮的,然后剩余的钱如果足够的话也都买当前轮的。

CODE
void solve()
{int n = 0;std::cin >> n;std::priority_queue<std::pair<int, int>> q;for (int i = 0, cnt = 1; i < n; i++, cnt++) {int a = 0;std::cin >> a;std::pair<int, int> tmp{ a, 0 };while (!q.empty() && q.top().first > a) {int cnt2 = q.top().first * q.top().second;q.pop();tmp.second += cnt2 / a;cnt += cnt2 % a;}tmp.second += cnt / a;cnt %= a;if (tmp.second >= 1)q.push(tmp);}int ans = 0;while (not q.empty()) {ans += q.top().second;q.pop();}std::cout << ans << '\n';
}

C

如果所有的数都不相同,那直接总长度 - 最长上升子序列的长度就是我们要的答案。因为我们要尽可能改变少的数。

如果有相同的数,那么两个相同的数之间的数得和这个数一起变化,即对于 x a1 a2 a3 a4 x\(f(ai) = f(x)\),我们可以把这些看成一块。每一块(单独一个数单独看成一块)对于最长上升序列的长度的贡献最多是 1,为了保证这一点,我们将每一块块内单独降序排序。然后对排好序的序列求最长上升子序列的长度。最后的答案就是序列中不同数的个数减去这个最长上升子序列的长度。

CODE
void solve() {int n = 0;std::cin >> n;std::vector a(n, 0);std::vector lst(n + 1, -1);int cnt = 0;for (int i = 0; i < n; i++) {std::cin >> a[i];if (lst[a[i]] == -1) {cnt++;}lst[a[i]] = i;}std::vector vis(n + 1, false);for (int i = 0; i < n; i++) {if (vis[i]) {continue;}int r = lst[a[i]];for (int j = i; j <= r; j++) {vis[j] = true;r = std::max(r, lst[a[j]]);}std::sort(a.begin() + i, a.begin() + r + 1, std::greater<int>());}std::vector dp(n + 1, Inf);dp[0] = 0;for (int i = 0; i < n; i++) {*std::lower_bound(dp.begin(), dp.end(), a[i]) = a[i];}int len = n;while (dp[len] == Inf) {len--;}std::cout << cnt - len << '\n';
}

D

将式子化简我们就得到了我们要找的其实是使 \(\sqrt{2}\sin({\pi \over 4} + \theta)\),其中 \(\theta\) 是两点连线的倾斜角,也就是最接近 \(\pi \over 4\)\(7\pi \over 4\) 的倾斜角。其实后者可以通过将整个图顺时针旋转 \(\pi \over 2\) 得到。我们只用找到里 \(\pi \over 4\) 最近的倾斜角就好了。

对于任意点 \((x, y)\),我们都有 \(y = x + d\),也就是说我们可以按截距将所有的点分类,分类后如果存在某一类有多个点,则我们就可确定倾斜角能够达到 \(\pi \over 4\) 我们就可以直接返回最优答案 \(\sqrt{2}\) 了。否则将所有点按照截距大小排序,最优答案一定是出现在相邻的两个点上的。这个证明画画三角形就可以了(三角形上至少有两个点是相邻的)。

CODE
double sqr2 = 1.4142135623730951;double solve(std::vector<std::pair<i64, i64>> b) {std::unordered_set<i64> s;for (auto &[x, y] : b) {if (s.count(y - x)) {return sqr2;}s.insert(y - x);}std::sort(b.begin(), b.end(), [](const std::pair<i64, i64> &a, const std::pair<i64, i64> &b) {return a.second - a.first < b.second - b.first;});double ans = 0;for (int i = 1; i < b.size(); i++) {// 两点所连直线的斜率if (b[i].second == b[i - 1].second) {ans = std::max(ans, 1.0);continue;}double k = (b[i].first - b[i - 1].first) * 1.0 / (b[i].second - b[i - 1].second);ans = std::max(ans, sqr2 * std::sin(3.14159265358979323846 / 4.0 + std::atan(k)));}return ans;
}int main()
{IOS;int _t = 1;std::cin >> _t;while (_t--) {int n = 0;std::cin >> n;std::vector<std::pair<i64, i64>> a(n);for (int i = 0; i < n; i++) {std::cin >> a[i].first >> a[i].second;}double ans = solve(a);for (int i = 0; i < n; i++) {std::swap(a[i].first, a[i].second);a[i].second = -a[i].second;}std::cout << std::fixed << std::setprecision(10) << std::max(ans, solve(a)) << '\n';}sp();return 0;
}

F

H

首先若要取出来的序列是不降的,则对于每次取出来的数都是确定的,我们只需要看目前从随机栈中取出当前应该取出的数的概率是多少。

CODE
void solve()
{int n = 0;std::cin >> n;std::vector a(2 * n, 0), b(0, 0);for (auto &i : a) {std::cin >> i;if (i != -1) {b.push_back(i);}}std::sort(b.begin(), b.end());std::vector cnt(n + 1, 0);int idx = 0, sum = 0;i64 ans = 1;for (int i = 0; i < 2 * n; i++) {if (a[i] == -1) {if (cnt[b[idx]] == 0) {std::cout << 0 << '\n';return;}(ans *= cnt[b[idx]] * inv(sum) % Mod) %= Mod;cnt[b[idx]]--;idx++;sum--;}else {cnt[a[i]]++;sum++;}}std::cout << ans << '\n';
}

J

对于任意给出的数都可能组成合数,因为凡是以 0, 2, 4, 6, 8, 5 这 6 个数之一结尾的五位数一定是合数,而题目给出了 5 个不同的数,一定至少包含上面的一个。最后注意一下 0 不要放在最前面就好了。

K

从节点 \(u\) 来看我们定义三种边:

  1. \(u -> v\) 表示 \(u\) 能作为 \(v\) 的父节点,反之不然。
  2. \(u <- v\) 表示 \(v\) 能作为 \(u\) 的父节点,反之不然。
  3. \(u -- v\) 两者谁做父亲都可以。

我们按以下条件 dfs 整个树:

  1. 不走第 1. 种边,
  2. 不走第 2. 种边,且记录碰到了几次第 2. 种边
  3. 要记录走过了多少点。

按照如上规则,我们 dfs 时会将整颗树分成若干块,并且我们还知道每块碰到了多少次第 2. 种边。如果任意一块碰到了两次及以上的第 2. 种边,整个图就是无解的。因为一个块碰到第 2. 种边意味着美丽节点只能在这一块之外的某一块,而碰到多个第 2. 种边就会产生矛盾,一个第 2. 种边说美丽节点只能在块 \(x\),另一个又说美丽节点只能在块 \(y\),由于图是树,所以 \(x \not = y\)。如果一个块没有碰到第 2. 种节点,那么这块的节点数就有可能是答案(因为还要检查是否有产生矛盾的块)。

CODE
std::vector<int> g[N + 5], a(N + 1, 0);
bool vis[N + 5];std::array<int, 2> dfs(int cur, int fa) {std::array<int, 2> res = { 1, 0 };vis[cur] = true;for (auto &to : g[cur]) {if (to == fa || 2 * a[cur] < a[to]) {continue;}if (2 * a[to] < a[cur]) {res[1]++;}else {auto [cnt, sum] = dfs(to, cur);res[0] += cnt;res[1] += sum;}} return res;
}void solve()
{int n = 0;std::cin >> n;for (int i = 1; i <= n; i++) {std::cin >> a[i];g[i].clear();vis[i] = false;}for (int i = 1; i < n; i++) {int u = 0, v = 0;std::cin >> u >> v;g[u].push_back(v);g[v].push_back(u);}int ans = 0;bool ok = true;for (int i = 1; i <= n; i++) {if (not vis[i]) {auto [cnt, sum] = dfs(i, 0);if (sum >= 2) {ok = false;break;}if (sum == 0) {ans = cnt;}}}std::cout << (ok ? ans : 0) << '\n';
}

L

我们最多同时解决 21 个问题,因为 \(22^4\) 就已经大于 \(2 \times 10^5\) 了,此时我还不如直接单独解决最远的那个问题。所以我们就可以dp 了,对于每一处 bug,枚举他和前面的多少个 bug 是一起解决的。

CODE
void solve() {int n,m;cin>>n>>m;vector<int>a(m+1);for(int i=1;i<=m;i++) cin>>a[i];vector<int>b(22,0);for(int i=1;i<=21;i++) b[i]=pow(i,4);int mx=m;for(int i=1;i<=m;i++) mx+=a[i];vector<int> dp(m+1,mx);dp[0]=0;dp[1]=1+a[1];for(int i=2;i<=m;i++){for(int j=1;j<=std::min(21ll, i);j++){dp[i]=min(dp[i],dp[i-j]+b[j]+a[i]);}}cout<<dp[m]<<"\n";
}

M

二分 K,然后求交集就好了。

CODE
void solve()
{int n = 0;std::cin >> n;std::vector a(n, 0ll), b(n, 0ll);for (auto &i : a) {std::cin >> i;}for (auto &i : b) {std::cin >> i;}i64 l = 0, r = Inf;while (l <= r) {i64 m = l + r >> 1;i64 L = 0, R = 2ll * Inf;for (int i = 0; i < n; i++) {L = std::max(L, a[i] - m * b[i]);R = std::min(R, a[i] + m * b[i]);}if (L <= R) {r = m - 1;}else {l = m + 1;}}std::cout << l << '\n';return;
}

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

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

相关文章

日报202535

今天总算是把项目组的事情解决了,于是正式开了Springboot+vue的学习,用了一晚上的时间配置好了环境(更新了JDK与Maven,重新设置了idea的设置) 然后了解了springboot的配置文件和基本使用,跑出了第一个spring的网页。这看着真有意思吧感觉比jsp方便不少。

Java SPI机制使用

1. Service Provider Interface SPI描述接口提供者优先规定接口要求,然后交由具体的实现者对接口进行内容的实现;2. 实现 //1. 定义接口 public Interface Demo_interface{//具体实现者必须要实现的内容void doexcute(); } //2.实现接口 public class Demo_Impl implements D…

互联网寒冬下,如何写好一份.NET求职简历?附带简洁免费的简历模板!!!

前言 在当今互联网行业的寒冬时期,每一位求职者都面临着更为激烈的竞争环境,如何在众多.NET候选人中脱颖而出,成为企业心仪的对象,用心准备一份简历显得尤为重要。简历不仅是个人职业经历的简要概述,更是向潜在雇主、HR展示你专业技能、项目经验、个人特质以及求职诚意的关…

注册github

今天成功注册了github账户,并上传了一个小项目。

HarmonyOS Next 属性动画和转场动画

HarmonyOS Next 属性动画和转场动画 在鸿蒙应用开发中,动画是提升用户体验的关键要素。通过巧妙运用动画,我们能让应用界面更加生动、交互更加流畅,从而吸引用户的注意力并增强其使用粘性。鸿蒙系统为开发者提供了丰富且强大的动画开发能力,其中属性动画是整个动画体系的核…

C语言小记

int a =10; int b=3; int c= pow(10,3); //表示10的三次方unsigned 表示不用补码表示 //数字的输入,%d 包括 char,short,int%u unsigned%ld long long%lu unsigned long long输入 float 是 %f double 是 %lf shuchu dou shi %f保留小数的话是大于5才入,小于等于5舍去强…

系统流程图联系

练习题一:图书馆借阅管理系统流程图绘制 背景说明:在学校图书馆借阅管理系统中,学生借阅图书需要经过一系列流程。首先,学生携带校园卡前往借阅处,工作人员通过刷卡设备读取学生信息,系统验证学生身份是否有效。若身份无效,系统提示原因(如校园卡过期、欠费等)。若身份…

推荐4本专著《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》、《TVM编译器原理与实践》、《LLVM编译器原理与实践》书,非常感谢

4本书推荐《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》、《TVM编译器原理与实践》、《LLVM编译器原理与实践》由清华大学出版社资深编辑赵佳霓老师策划编辑的新书《AI芯片开发核心技术详解》已经出版,京东、淘宝天猫、当当等网上,相应陆陆续续可以购买。该…