2021牛客暑期多校训练营5 个人补题记录
比赛链接:Here
1001 - Away from College
1002 - Boxes
思路:只要使用一次hints,以后的每一步都可以知道剩下多少个黑球。所以最少花费是全部盒子开一遍或者先用一次hints后面再碰运气,注意到,每开一个盒子都有一定概率直接结束(后面全都是白球或全都是黑球)
所以先排序,枚举前缀和至倒数第二个盒子,再乘以概率
最后答案为:
试一下样例
前缀和分别是
代码
const int N = 1e5 + 10;
double a[N];
int main() {
// cin.tie(nullptr)->sync_with_stdio(false);
int n; double c;
cin >> n >> c;
double sum = 0.0, ans = 0.0;
for (int i = 1 ; i <= n; ++i) cin >> a[i], sum += a[i];
sort(a + 1, a + 1 + n);
double f = 1.0;
for (int i = n; i > 0; i -= 1) {
ans += (1.0 - f) * a[i];
f /= 2.0;
}
cout << fixed << setprecision(6) << min(sum, c + ans);
}
1003 - Cheating and Stealing
1004 - Double Strings
超级眼熟,没想到就是 19年 CCPC秦皇岛 C 题的改版。
引用一下官网题解
好的方案的构成是“一段相同的前缀+一个不同字符(a比b小)+长度相同的任意后缀”。枚举不同的字符在两个序列中的位置。
用
长度相同的任意后缀也可以用类似的 dp 计算,或者设 A 中此时剩余长度为 x, B 中剩余长度为 y,不失一般性地设
using ll = long long;
#define mod 1000000007
ll la, lb, adf[5010], adg[5010], f[5010], g[5010];
char a[5010], b[5010];
int main() {
cin >> a + 1 >> b + 1;
la = strlen(a + 1);
lb = strlen(b + 1);
for (int i = 1; i <= la; i++) {
for (int j = 1; j <= lb; j++) adf[j] = adg[j] = 0;
for (int j = 1; j <= lb; j++) {
if (a[i] == b[j]) adg[j] = g[j - 1] + 1;
adf[j] = f[j - 1];
if (a[i] < b[j]) adf[j] += g[j - 1] + 1;
}
for (int j = 1; j <= lb; j++) {
adg[j] += adg[j - 1];
adf[j] += adf[j - 1];
g[j] += adg[j];
f[j] += adf[j];
adg[j] %= mod; adf[j] %= mod;
g[j] %= mod; f[j] %= mod;
}
}
cout << (f[lb] % mod + mod) % mod;
return 0;
}
1005 - Eert Esiwtib
1006 - Finding Points
1007 - Greater Integer, Better LCM
1008 - Holding Two (签到)
题目描述
在
请问是否存在任意3个点
如果存在则输出任何一种情况,否则输出 -1
简单来说就是满足在横行,竖行,斜行中任意的连续的3个的元素不能都为0,或都为1;
考虑了挺多情况发现下面这种写法对于任何
【AC Code】
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n, m; cin >> n >> m;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j)
cout << ((i & 1) ? ((j + 1) / 2 % 2) : !((j + 1) / 2 % 2));
cout << "\n";
}
}
1009 - Interval Queries
看不懂,没思路,fw二连
1010 - Jewels
题目描述
把大海想象成一个三维坐标,我们的坐标为
开赛的时候看了下这个似乎是贪心排序就能写?自信交了一发,WA打脸。之后队友看出
才是签到,所以就比赛时没管这道题了
正解的思路:所有的宝石肯定都在
稍微套一下板子就可以了
代码
ll n, ans;
struct jew {ll z, v, id;} a[310];
ll f(ll t, jew x) {t--; return t * t * x.v * x.v + 2 * t * x.v * x.z;} //边权
void g(int x) {
int t;
for (int i = 1; i <= n; i++) //找到当前宝石所匹配的时间
if (a[i].id == x) {t = i; break;}
for (int i = 1; i <= n; i++) { //枚举所有的边
if (f(i, a[i]) + f(t, a[t]) > f(t, a[i]) + f(i, a[t])) { //找增广路
swap(a[i], a[t]); //匹配宝石到时间更优的位置
g(a[t].id); g(x); //暴力递归找增广路
}
}
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
ll x, y, z, v; cin >> x >> y >> z >> v;
ans += x * x + y * y + z * z;
a[i] = (jew) {z, v, i};
}
for (int i = 1; i <= n; i++) g(i);
for (int i = 1; i <= n; i++) ans += f(i, a[i]); //累加答案
cout << ans << "\n";
return 0;
}
1011 - King of Range
题目描述
长度
令
因为区间端点是单调的,明显的求单调队列问题。
其中一个递增序列,队首维护最小值,一个递减序列,队首维护最大值,每次弹出两个队列中队首靠前的一个,直到极差
不过需要同时维护两个(一个求最大值,另一个求最小值)
代码
const int N = 1e5 + 10;
int a[N], q1[N], q2[N], h1, t1, h2, t2;
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n, q;
cin >> n >> q;
for (int i = 1; i <= n; ++i) cin >> a[i];
while (q--) {
int k;
cin >> k;
h1 = h2 = t1 = t2 = 1;
q1[1] = q2[1] = 1;
int j = 1;
ll ans = 0;
for (int i = 1; i <= n; ++i) {
if (q1[h1] < i) ++h1;
if (q2[h2] < i) ++h2;
while (j < i || a[q2[h2]] - a[q1[h1]] <= k) {
if (j == n)break;
++j;
while (t1 >= h1 && a[q1[t1]] > a[j])--t1;
while (t2 >= h2 && a[q2[t2]] < a[j])--t2;
q1[++t1] = j;
q2[++t2] = j;
}
if (a[q2[h2]] - a[q1[h1]] <= k) break;
ans += n - j + 1;
}
cout << ans << "\n";
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· 分享4款.NET开源、免费、实用的商城系统
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 全程不用写代码,我用AI程序员写了一个飞机大战
2020-07-31 线段树 - 多组图带你从头到尾彻底理解线段树
2020-07-31 ZOJ - 1610 区间修改+暴力单点查询
2020-07-31 什么是离散化?C++实现方法
2020-07-31 离散化/线段树 (POJ - 2528 Mayor's posters)
2020-07-31 HDU--1166--单点更新