SMU Summer 2024 Contest Round 2

Sierpinski carpet

题意

给一个整数 n ,输出对应的 \(3^n\times 3^n\) 的矩阵。

思路

\(n = 0\) 时是 # ,之后每级矩阵都是中间 \(3^{n-1}\times 3^{n-1}\) 矩阵为全点,周围八个矩阵为上一级的图案,按题意模拟即可。

代码

#include<bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); int n;
cin >> n; map<int, vector<string>> mp;
mp[0] = {"#"}; auto ok = [&](vector<string> s, int m)->vector<string> {
const int sn = s.size();
int N = 3;
for (int i = 1; i < m; i ++) {
N *= 3;
} vector<string> res(N);
for (int i = 0; i < N ; i ++) {
string cs;
if (i >= N / 3 && i < N / 3 * 2) {
cs += s[i % sn] + string(sn, '.') + s[i % sn];
} else {
cs += s[i % sn] + s[i % sn] + s[i % sn];
}
res[i] = cs;
} return res;
}; for (int i = 1; i <= n; i ++) {
mp[i] = ok(mp[i - 1], i);
} for (auto &i : mp[n])
cout << i << '\n'; return 0;
}

Consecutive

题意

给一个字符串,\(Q\) 次询问 \([l,r]\) 区间内有多少对相邻且相同的字母。

思路

前缀和处理,注意边界需要特判一下。

代码

#include<bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); int n, q;
cin >> n >> q; string s;
cin >> s; s = " " + s;
vector<int> pre(n + 1);
for (int i = 1; i <= n; i ++) {
pre[i] = pre[i - 1];
if (s[i] == s[i + 1]) pre[i] ++;
} while (q--) {
int l, r;
cin >> l >> r;
cout << pre[r] - pre[l - 1] - (r < n && s[r] == s[r + 1]) << '\n';
} return 0;
}

Minimum Width

题意

给你 n 个数,每个数代表一个单词的长度,单词之间挨着的间距为 1 ,行首间距不算,现要求你设计一行的长度 w ,使得这些单词最多排列 m 行,问 w 最小是多少。

思路

w 越大,排列行数一定越小,所以答案满足单调性,可以二分答案,需要注意的是最小边界应该是单词中长度最大的那个,或者在 check 的时候特判一下。

代码

#include<bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); int n, m;
cin >> n >> m; vector<i64> L(n + 2);
for (int i = 1; i <= n; i ++)
cin >> L[i];
L[n + 1] = LLONG_MAX / 2; auto check = [&](i64 x) -> bool{
i64 res = 0, now = 0;
for (int i = 1; i <= n; i ++) {
if (x < L[i]) return false;
now += L[i];
if (now + 1 + L[i + 1] > x) {
now = 0;
res ++;
} else {
now ++;
}
if (res > m) return false;
}
return res <= m;
}; i64 l = 0, r = 10000000000000000ll, ans = 1; while (l <= r) {
i64 mid = l + r >> 1;
if (check(mid)) r = mid - 1, ans = mid;
else l = mid + 1;
} cout << ans << '\n'; return 0;
}

Printing Machine

题意

给你 n 个景点的开门时间和持续时间,你想到这些景点去打卡,只要在开门时间或者关门时的那瞬间打卡都可以,但是每打卡一次你需要休息 1 单位时间,问你最多可以打卡多少个景点。

思路

考虑贪心。

要使得打卡景点最多,首先应该考虑开门最早并且持续时间短的景点,所以可以将这些区间先排序,且数据范围给到了 1e18,所以不能去枚举单位时间,对于在当前时间开门的所有景点,我们可以把它的关门时间丢进优先队列里,优先去最早关门的店,如果有景点的关门时间比当前时间更早,说明我们无法去这个景点,弹出队列即可,如果当前时间没有景点开门,我们直接跳到最近一个景点的开门时间即可。

代码

#include<bits/stdc++.h>

using namespace std;

using i64 = long long;

using PII = pair<i64, i64>;

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); int n;
cin >> n; vector<PII> td(n);
for (auto &[t, d] : td) {
cin >> t >> d;
d += t;
} sort(td.begin(), td.end()); priority_queue<i64, vector<i64>, greater<>> Q;
i64 time = 1, ans = 0, pos = 0; while (true) {
if (Q.empty()) {
if (pos == n) break;
time = td[pos].first;
Q.push(td[pos++].second);
}
while (pos < n && td[pos].first == time)
Q.push(td[pos++].second);
while (Q.size() && Q.top() < time)
Q.pop();
if (Q.size()) ans ++, Q.pop();
time ++;
} cout << ans << '\n'; return 0;
}

Nearest Black Vertex

题意

给你 n 个点,m 条边的无向连通图,你可以将这些点染成黑白两色,现给你 k 个条件,要求使得对于第 \(P_i\) 个点,它与离他最近的黑色的点距离为 \(D_i\),问是否有染色方案可以满足这些条件,有就输出 \(Yes\) 和对应方案,否则输出 \(No\)。

思路

首先可以用 BFS 先计算出每个点到其他点的距离,其次先默认全部点都是黑色,然后去遍历 k 个条件,将与 \(P_i\) 点距离小于 \(D_i\) 的点都染成白色,处理出最终黑色的点,然后再去遍历一次条件,判断所有黑点与 \(P_i\) 的最小距离是否为 \(D_i\) 即可。

代码

#include<bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); int n, m;
cin >> n >> m; vector g(n + 1, vector<int>());
for (int i = 0; i < m; i ++) {
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
} vector dis(n + 1, vector<int>(n + 1));
auto bfs = [&](int s) {
vector<bool> vis(n + 1);
queue<array<int, 2>> Q;
Q.push({s, 0}); while (Q.size()) {
auto [u, len] = Q.front();
Q.pop(); if (vis[u]) continue;
vis[u] = 1; dis[s][u] = len;
for (auto &v : g[u]) {
if (!vis[v] && v != u) {
Q.push({v, len + 1});
}
}
}
}; for (int i = 1; i <= n; i ++)
bfs(i); int k;
cin >> k; vector<bool> col(n + 1, 1);
vector<array<int, 2>> pd(k);
for (auto &[p, d] : pd) {
cin >> p >> d;
for (int i = 1; i <= n; i ++)
if (dis[p][i] < d)
col[i] = 0;
} for (auto &[p, d] : pd) {
int t = 1 << 30;
for (int i = 1; i <= n; i ++)
if (col[i])
t = min(t, dis[p][i]);
if (t != d) {
cout << "No\n";
return 0;
}
} cout << "Yes\n";
for (int i = 1; i <= n; i ++)
cout << col[i]; return 0;
}

Christmas Present 2

题意

给你一个起点和 n 个孩子的位置,你每次从家出发可以带 k 个礼物,也可以随时回家,现你需要从起点出发按顺序把礼物发个 n 个孩子,送完礼物后最终回到家,问你这个送礼物的最短路程。

思路

因为按顺序发礼物,所以当你处在第 \(i\) 个位置时,就是在 \(i-k\) 到 \(i-1\) 的位置中选择一处回家,考虑dp。

设 \(dp_i\) 为从起点到第 \(i\) 个孩子的最短路程,假设在 \(j\) 处回家,那么转移方程为:

\[dp_i=Min_{i-k}^{i-1}dp_j+home_j+home_{j+1}+dis_{(j+1,i)}
\]

对于 \(dis_{(j+1,i)}\) 可以用前缀和处理成 \(Pre_i - Pre_{j+1}\),那么可化为:

\[dp_i=Min_{i-k}^{i-1}dp_j+home_j+home_{j+1}+Pre_i-Pre_{j+1}\\
=Pre_i+Min_{i-k}^{i-1}dp_j+home_j+home_{j+1}-Pre_{j+1}
\]

对于后面的 \(Min\) 的一串可以使用单调队列 \(O(n)\) 优化。

注意单调队列开始应该放入一个 0,表示给前面的 k 个孩子发礼物后可以不回家。

代码

#include<bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); int n, k;
cin >> n >> k; vector<array<double, 2>> loc(n + 1);
for (auto &[x, y] : loc)
cin >> x >> y; vector<double> home(n + 1), pre(n + 1), dp(n + 1);
for (int i = 1; i <= n; i ++) {
home[i] = hypot(loc[i][0] - loc[0][0], loc[i][1] - loc[0][1]);
pre[i] += pre[i - 1];
pre[i] += hypot(loc[i][0] - loc[i - 1][0], loc[i][1] - loc[i - 1][1]);
} auto calc = [&](int j)->double{
if (!j) return 0;
return dp[j] + home[j] + home[j + 1] - pre[j + 1];
}; deque<int> Q;
Q.push_back(0);
for (int i = 1; i <= n; i ++) {
dp[i] = pre[i] + calc(Q.front()); while (Q.size() && Q.front() <= i - k)
Q.pop_front(); while (Q.size() && calc(Q.back()) >= calc(i))
Q.pop_back(); Q.push_back(i);
} printf("%.15lf", dp[n] + home[n]); return 0;
}

SMU Summer 2024 Contest Round 2的更多相关文章

  1. 2015 Astar Contest - Round 3 题解

    1001 数长方形 题目大意 平面内有N条平行于坐标轴的线段,且不会在端点处相交 问共形成多少个矩形 算法思路 枚举4条线段的全部组合.分别作为矩形四条边.推断是否合法 时间复杂度: O(N4) 代码 ...

  2. Contest Round #451 (Div. 2)F/Problemset 898F Restoring the Expression

    题意: 有一个a+b=c的等式,去掉两个符号,把三个数连在一起得到一个数 给出这个数,要求还原等式,length <= 1e6 三个数不能含有前导0,保证有解 解法: 铁头过题法,分类然后各种判 ...

  3. Codeforces Round #284 (Div. 2)A B C 模拟 数学

    A. Watching a movie time limit per test 1 second memory limit per test 256 megabytes input standard ...

  4. Sending messages to non-windowed applications -- AllocateHWnd, DeallocateHWnd

    http://delphi.about.com/od/windowsshellapi/l/aa093003a.htm Page 1: How Delphi dispatches messages in ...

  5. Codeforces 240 F. TorCoder

    F. TorCoder time limit per test 3 seconds memory limit per test 256 megabytes input input.txt output ...

  6. cf499B-Lecture 【map】

    http://codeforces.com/problemset/problem/499/B B. Lecture     You have a new professor of graph theo ...

  7. Codeforces 240F. TorCoder 线段树

    线段树统计和维护某一区间内的字母个数.. . . F. TorCoder time limit per test 3 seconds memory limit per test 256 megabyt ...

  8. 物联网学生科协第三届H-star现场编程比赛

    问题 A: 剪纸片 时间限制: 1 Sec 内存限制: 128 MB 题目描写叙述 这是一道简单的题目,假如你身边有一张纸.一把剪刀.在H-star的比赛现场,你会这么做: 1. 将这张纸剪成两片(平 ...

  9. [cf contest 893(edu round 33)] F - Subtree Minimum Query

    [cf contest 893(edu round 33)] F - Subtree Minimum Query time limit per test 6 seconds memory limit ...

  10. 水题 Codeforces Round #307 (Div. 2) A. GukiZ and Contest

    题目传送门 /* 水题:开个结构体,rk记录排名,相同的值有相同的排名 */ #include <cstdio> #include <cstring> #include < ...

随机推荐

  1. onreadystatechange 属性

    onreadystatechange 属性是 XMLHttpRequest 对象的一个事件处理器,用于在 XMLHttpRequest 对象的 readyState 属性发生变化时触发.这个属性通常用 ...

  2. Spring-jdbcTempalate研究

    很多时候,需要使用jdbcTemplate,既有出于性能考虑的因素,也有出于个人偏好. 关于jdbcTemplate的几个关键性的问题: 一.简介 JdbcTemplate位于org.springfr ...

  3. detect.py - yolov5master nvidia jetson agx xavier for mask with UART

    import argparse import time from pathlib import Path import cv2 import torch import torch.backends.c ...

  4. CF1854E Games Bundles

    乱搞题 设个 \(dp[i]\) 表示和为 \(i\) 的子序列个数,那么转移是容易的, \(dp[j]+=dp[j-i]\) ,然后就判下 \(dp[60]+dp[60-i]\) 是否大于 \(m\ ...

  5. Codeforces Round 941 (Div. 2) cf 941 div2 A~D

    每题都有AC代码在伸缩代码框请留意!! A. Card Exchange -------------------------------------------题解------------------ ...

  6. 静态 top tree 入门

    理论 我们需要一个数据结构维护树上的问题,仿照序列上的问题,我们需要一个方法快速的刻画出信息. 比如说线段树就通过分治的方式来通过将一个区间划分成 \(\log n\) 个区间并刻画出这 \(\log ...

  7. 树莓派4B-高精度驱动步进电机

    树莓派4B-高精度驱动步进电机 项目介绍 利用4B树莓派控制步进电机转动,精度可达:0.0144度 (即360度/25000) 适用于非常精密的角度转动. 舵机的精度为1度,无法实现超高精度控制. 硬 ...

  8. MySQL中为什么要使用索引合并(Index Merge)?

    本文分享自华为云社区<[华为云MySQL技术专栏]MySQL中为什么要使用索引合并(Index Merge)?>,作者:GaussDB 数据库. 在生产环境中,MySQL语句的where查 ...

  9. boltdb一瞥

    boltdb 网上关于boltdb的文章有很多,特别是微信公众号上,例如: boltdb源码分析系列-事务-腾讯云开发者社区-腾讯云 (tencent.com) 这些文章都写的挺好,但不一定覆盖了我所 ...

  10. oeasy教您玩转vim - 84 - # 命令command

    ​ 命令 command 回忆 关于 函数function 可以调用别的函数 :call append(0,"oeasy o2z o3z") 还可以执行表达式 :call exec ...