牛客周赛 Round 62

news/2024/10/1 1:05:19

A-小红的字符移动

签到题

代码

#include <iostream>using namespace std;int main()
{string s;cin >> s;swap(s[0], s[1]);cout << s;
}

B-小红的数轴移动

一道模拟题吧,按题意要求进行操作。

代码

#include <iostream>using namespace std;typedef long long ll;const int N = 1e5 + 10;int a[N];int main()
{int n, x;cin >> n >> x;ll res = 0;while (n --){if (x == 0) break;ll k;cin >> k;if (x > 0) x -= k;else x += k;res += k;}cout << res;return 0;
}

C-小红的圆移动

题目看太快看歪了,赛时解法对的,但做了一堆无效操作。

思路

题意要求包含原点的圆不超过k个,所以枚举每个圆,通过圆心到原点的距离和半径比较,判断是否包含圆心。记录包含圆心的圆的个数设为cnt,cnt <= k则直接输出0,不需要进行移动;cnt > k需要移动cnt - k个圆,移动代价是距离乘圆的面积,可以在枚举圆的时候,将包含原点的圆移动的代价存下来,进行排序,将代价较小的圆优先移动。

代码

#include <iostream>
#include <algorithm>
#include <cmath>#define fi first
#define se secondusing namespace std;typedef long long ll;const double pi = acos(-1);
const int N = 1e5 + 10;pair<double, ll> a[N];
double b[N];double S(ll r)
{return pi * r * r;
}double p(double x, ll r)
{return fabs(x) * S(r);
}int main()
{int n, k;cin >> n >> k;int cnt = 0;for (int i = 0; i < n; i ++){ll x, y, r;cin >> x >> y >> r;double d = sqrt(x * x + y * y);if (d - r < 0) b[cnt ++] = p(d - r, r);}if (cnt <= k) {cout << 0;}else {sort(b, b + cnt);double res = 0;for (int i = 0; i < cnt - k; i ++)res += b[i];printf("%.12lf", res);}return 0;
}

D-小红的树上移动

思路

注意题目说当前节点的邻点中不存在白色节点,则停止移动,根据树的定义,容易知道,停下移动的节点就是叶子节点,且移动过程必然是从根节点一路走到叶子节点。则当前路径的红色节点数量的期望就等于路径节点数量*选择走这条路径的概率,概率求法就是每个分叉点的概率之积。最终答案就是将所有叶子节点的期望求和。

代码

赛时bfs写法

#include <iostream>
#include <vector>
#include <queue>using namespace std;typedef long long ll;const int mod = 1e9 + 7;
const int N = 1e5 + 10;int n;
vector<int> g[N];
ll sz[N];
ll p[N];
bool st[N];ll qmi(ll a, ll b)
{ll res = 1;while (b){if (b & 1) res = res * a % mod;a = a * a % mod;b >>= 1;}return res;
}ll inv(ll x)
{return qmi(x, mod - 2);
}void bfs()
{queue<int> q;q.push(1);sz[1] = 1;while (!q.empty()){int t = q.front();q.pop();st[t] = 1;for (int i : g[t]){if (st[i]) continue;sz[i] = sz[t] + 1;p[i] = p[t] * (g[t].size() - (t != 1)) % mod;q.push(i);}}
}int main()
{cin >> n;for (int i = 1; i <= n; i ++) p[i] = 1;   for (int i = 1; i < n; i ++){int u, v;cin >> u >> v;g[u].push_back(v);g[v].push_back(u);}bfs();ll res = 0;for (int i = 2; i <= n; i ++)if (g[i].size() == 1)res = (res + sz[i] * inv(p[i]) % mod) % mod;cout << res;return 0;
}

dfs代码

#include <iostream>
#include <vector>
#include <queue>using namespace std;typedef long long ll;const int mod = 1e9 + 7;
const int N = 1e5 + 10;int n;
vector<int> g[N];
ll sz[N];
ll p[N];
bool st[N];ll qmi(ll a, ll b)
{ll res = 1;while (b){if (b & 1) res = res * a % mod;a = a * a % mod;b >>= 1;}return res;
}ll inv(ll x)
{return qmi(x, mod - 2);
}int dfs(int u, int fa)
{int cnt = 0, sum = 0;for (int i : g[u]){if (i == fa) continue;cnt ++;sum = (sum + dfs(i, u)) % mod;}return (1 + sum * inv(cnt) % mod) % mod;
}int main()
{cin >> n; for (int i = 1; i < n; i ++){int u, v;cin >> u >> v;g[u].push_back(v);g[v].push_back(u);}cout << dfs(1, 0);return 0;
}

EF-小红的中位数查询

一道主席树的板子题吧。看下官方的题解吧,讲的太好了。
当然也可以用划分树。。。

代码

#include <iostream>
#include <algorithm>
#include <vector>using namespace std;const int N = 1e5 + 10;int n, m;
int a[N];
vector<int> nums;struct node {int l, r;int cnt;
} tr[N * 4 + N * 17];int root[N], idx;int find(int x)
{return lower_bound(nums.begin(), nums.end(), x) - nums.begin();
}int build(int l, int r)
{int p = ++ idx;if (l == r) return p;int mid = l + r >> 1;tr[p].l = build(l, mid), tr[p].r = build(mid + 1, r);return p;
}int insert(int p, int l, int r, int x)
{int q = ++ idx;tr[q] = tr[p];if (l == r) {tr[q].cnt ++;return q;}int mid = l + r >> 1;if (x <= mid) tr[q].l = insert(tr[p].l, l, mid, x);else tr[q].r = insert(tr[p].r, mid + 1, r, x);tr[q].cnt = tr[tr[q].l].cnt + tr[tr[q].r].cnt;return q;
}int query(int q, int p, int l, int r, int k)
{if (l == r) return r;int cnt = tr[tr[q].l].cnt - tr[tr[p].l].cnt;int mid = l + r >> 1;if (k <= cnt) return query(tr[q].l, tr[p].l, l, mid, k);else return query(tr[q].r, tr[p].r, mid + 1, r, k - cnt);
}int main()
{cin >> n >> m;for (int i = 1; i <= n; i ++){cin >> a[i];nums.push_back(a[i]);}sort(nums.begin(), nums.end());nums.erase(unique(nums.begin(), nums.end()), nums.end());root[0] = build(0, nums.size() - 1);for (int i = 1; i <= n; i ++)root[i] = insert(root[i - 1], 0, nums.size() - 1, find(a[i]));while (m --){int l, r, k;cin >> l >> r;k = (r - l + 2) / 2;cout << nums[query(root[r], root[l - 1], 0, nums.size() - 1, k)] << '\n';}return 0;
}

G-小红的数轴移动(二)

01背包。做法和蓝桥的砝码称重有点像,这里改求选择最少操作到达目标值,多一个求选择的先后序。

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <vector>using namespace std;const int M = 10000;
const int N = 1e5 + 10;int a[N], dp[110][M * 2];
vector<int> hp[M];
int n, k;
set<int> v;int main()
{cin >> n >> k;int sum = 0;for (int i = 1; i <= n; i ++){cin >> a[i];sum += a[i];hp[a[i]].push_back(i);v.insert(i);}memset(dp, 0x3f, sizeof dp);dp[0][M + k] = 0;for (int i = 1; i <= n; i ++){for (int j = -M; j <= M; j ++) dp[i][M + j] = dp[i - 1][M + j];for (int j = -M; j <= M; j ++){if (j + a[i] <= M) dp[i][j + M + a[i]] = min(dp[i][j + M + a[i]], dp[i - 1][j + M] + a[i]);if (j - a[i] >= -M) dp[i][j + M - a[i]] = min(dp[i][j + M - a[i]], dp[i - 1][j + M] + a[i]);}}if (dp[n][M] == 0x3f3f3f3f) {cout << sum << '\n';for (int i =  1; i <= n; i ++) cout << i << ' ';return 0;}vector<int> l, r, ans;int res = dp[n][M], j = 0;cout << res << '\n';for (int i = n; i; i --){if (dp[i][j + M] == dp[i - 1][j + M]) continue;if (j + a[i] <= M && dp[i][j + M] == dp[i - 1][j + M + a[i]] + a[i]) {l.push_back(hp[a[i]].back());v.erase(hp[a[i]].back());hp[a[i]].pop_back();j += a[i];res -= a[i];}if (j - a[i] >= -M && dp[i][j + M] == dp[i - 1][j + M - a[i]] + a[i]) {r.push_back(hp[a[i]].back());v.erase(hp[a[i]].back());hp[a[i]].pop_back();j -= a[i];res -= a[i];}}while (k != 0){if (k < 0) {k += a[r.back()];ans.push_back(r.back());r.pop_back();}else {k -= a[l.back()];ans.push_back(l.back());l.pop_back();}}for (int i : ans) cout << i << ' ';for (int j : v) cout << j << ' ';return 0;
}

另一个做法,图论。
将区间偏移100,考虑(100, 200]内每个点i是由i-a[i]的点转移过来的,边权是a[i],[0, 100)内每个点i是由i+a[i]的点转移过来的,边权是a[i]。然后以x+100作为起点,做dijkstra求最短路。注意跑当前路径的时候,每个点只能选一遍,同时将前驱节点记录下来。

#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>using namespace std;typedef long long ll;const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 2e5 + 10;struct node {ll v, w, id;
};struct edge {ll v, w, id;vector<bool> vis;bool operator < (const edge& a) const {return w > a.w;}
};int n, x;
ll a[N], dist[N], pre[N], pred[N];
bool st[N], vst[N];
vector<node> g[N];void dijkstra()
{memset(dist, 0x3f, sizeof dist);priority_queue<edge> pq;dist[x + 100] = 0;vector<bool> vis(n + 1, 0);pq.push({x + 100, 0, 0, vis});while (!pq.empty()){auto [u, w, fa, vv] = pq.top();pq.pop();if (vst[u]) continue;vst[u] = 1;for (auto [v, c, id] : g[u]){if (dist[v] > w + c && !vv[id]){dist[v] = w + c;pre[v] = u;pred[v] = id;vector<bool> vs = vv;vs[id] = 1;pq.push({v, w + c, id, vs});}}}
}int main()
{cin >> n >> x;ll sum = 0;for (int i = 1; i <= n; i ++){cin >> a[i];sum += a[i];for (int j = 0; j <= 200; j ++)if (j > 100) g[j].push_back({j - a[i], a[i], i});else if (j < 100) g[j].push_back({j + a[i], a[i], i});}dijkstra();if (dist[100] == INF) {cout << sum << '\n';for (int i = 1; i <= n; i ++) cout << i << ' ';return 0;}cout << dist[100] << '\n';int ne = 100;vector<int> ans;if (pre[ne]) {while (ne != x + 100){ans.push_back(pred[ne]);st[pred[ne]] = 1;ne = pre[ne];}}reverse(ans.begin(), ans.end());for (int i = 1; i <= n; i ++)if (!st[i]) ans.push_back(i);for (int i : ans) cout << i << ' ';return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

KeyShot基础操作1

KeyShot的基本操作,包含视图、导入导出、各个面板简介等内容。注:学习此软件纯粹是工作中突然要我去对接模型厂家,厂家不能对外提供模型原件,于是就自己学了下这个软件渲染模型。--本篇导航--快捷键 视图操作(视图基本操作、几何图形视图) 模型导入、工程保存导出 各个面…

高级语言程序设计第二次个人作业

班级链接:https://edu.cnblogs.com/campus/fzu 作业要求链接:https://edu.cnblogs.com/campus/fzu/2024C/homework/13282 学号:102400130 姓名:杨子旭 章节习题在第四题的时候发现即使代码正确也无法输出正确结果,最后发现是win7系统原因,测试发现在win10的系统可以转为十…

YouTube 注释 All In One

YouTube 注释 All In OneYouTube 注释 All In One old YouTube 批注是在视频上添加文字层,链接或热点。 他们添加了链接到其他网站或视频的交互式框(您想要的任何链接)。https://zh-cn.aiseesoft.com/how-to/add-annotations-to-youtube.html将注释支持带回 YouTube™! 201…

AnimationClip优化工具 - 删除连续相同的帧

下图中Rotation.z的前4个关键帧[0, 3](即15帧, 30帧, 45帧, 60帧),值都没变; (3, 4)Rotation.z变为60(即61帧到90帧); 后3个关键帧[5, 7]一直维持在60没变。可以分析下:前4个关键帧,[1, 2]删除对动画没影响,后3个关键帧[5, 7]删除对动画也没影响。public class AnimC…

实验1 C语言输入输出和简单程序编写

一,实验目的 1. 会使用C语言程序开发环境(vs2010/devc++等),能熟练、正确使用它们编写、编译、运行、调 试C程序 2. 知道C程序结构和编码规范,能正确使用 3. 能正确、熟练使用C语言输入输出函数: scanf() , printf() , getchar() , putchar() 4. 能灵活、组合使用基本数据…

VScode Cmake-tools 部分问题记录

我的 Visual Studio Code 先前一直安装了 cpp-tools 和 cmake-tools。随后,我升级了我的 GCC 环境版本。然而,重新启动 Visual Studio Code 后,旧的 GCC 版本仍保留在工具包中。起初,我以为是 cpp-tools 插件的问题,一直无法解决这个 bug。后来卸载了相关插件后才发现是 c…

数组0.1

一维数组 数组的运用场合 当我们需要涉及的变量特别多,光想名字都要想半天 所以引入数组 Q: (1)在程序中怎样存放100个学生的成绩? (2)定义100个整型变量吗? (3)C语言中的解决方案是……? A: (1)存储学生成绩用整型数组 mark[100]; (2)存储一行文字用字符数组 …

opencascade AIS_WalkDelta、AIS_ViewInputBuffer源码学习工作

opencascade AIS_WalkDelta 前言 运行方法 1. 空构造函数。 AIS_WalkDelta() : myIsDefined(false), myIsJumping(false), myIsCrouching(false), myIsRunning(false) {} 2. 返回平移组件。 const AIS_WalkPart& operator[] (AIS_WalkTranslation thePart) ; 3. 返回平移组…