T1:Water Station
模拟
代码实现
// C++实现
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
int ans = round(n/5.)*5;
cout << ans << '\n';
return 0;
}
// Python实现
n = int(input())
ans = int(round(n/5, 0))*5
print(ans)
T2:ABCDEFG
可以把边权挂在左边的点上,求一遍区间和即可
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
char p, q;
cin >> p >> q;
vector<int> d = {3, 1, 4, 1, 5, 9};
if (p > q) swap(p, q);
p -= 'A'; q -= 'A';
int ans = 0;
for (int i = p; i < q; ++i) {
ans += d[i];
}
cout << ans << '\n';
return 0;
}
T3:Snuke the Cookie Picker
找出矩形所在的四个边界
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int h, w;
cin >> h >> w;
vector<string> s(h);
rep(i, h) cin >> s[i];
int li = h, lj = w, ri = 0, rj = 0;
rep(i, h)rep(j, w) {
if (s[i][j] == '#') {
li = min(li, i);
lj = min(lj, j);
ri = max(ri, i);
rj = max(rj, j);
}
}
for (int i = li; i <= ri; ++i) {
for (int j = lj; j <= rj; ++j) {
if (s[i][j] == '.') {
cout << i+1 << ' ' << j+1 << '\n';
}
}
}
return 0;
}
T4:Sleep Log
记 \(f(x)\) 表示前 \(x\) 分钟的睡眠睡觉,那么带求的答案就是 \(f(r) - f(l)\)
先预处理出睡眠时间的前缀和 \(s\)
然后二分找到 \(x\) 所在时间段的左端点位置 \(i\)
最后 \(f(x)\) 就是 \(s[i]\) 加上剩余部分的睡眠时间
如何计算剩余部分的睡眠时间?
- 如果 \(x\) 位于睡觉时间段,那么这一部分的贡献就是 \(x-A_i\)
- 如果 \(x\) 位于不睡觉时间段,那么这一部分的贡献就是 \(0\)
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n;
cin >> n;
vector<int> a(n);
rep(i, n) cin >> a[i];
vector<int> s(n);
for (int i = 1; i < n; ++i) {
s[i] = s[i-1];
if (i%2 == 0) s[i] += a[i]-a[i-1];
}
auto f = [&](int x) {
int i = lower_bound(a.begin(), a.end(), x) - a.begin() - 1;
if (i < 0) return 0;
int res = s[i];
if (i%2 == 1) res += x-a[i];
return res;
};
int q;
cin >> q;
rep(qi, q) {
int l, r;
cin >> l >> r;
int ans = f(r)-f(l);
cout << ans << '\n';
}
return 0;
}
T5:Art Gallery on Graph
\(\operatorname{Dijkstra}\) 的变种题
记 d[v] 表示点 \(v\) 处剩余体力的最大值
然后用 \(\operatorname{Dijkstra}\) 求出每个点的 \(d[v]\) 即可
最后如果 \(d[v] \geqslant 0\),则说明点 \(v\) 就是被保护的点
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using P = pair<int, int>;
int main() {
int n, m, k;
cin >> n >> m >> k;
vector<vector<int>> to(n);
rep(i, m) {
int a, b;
cin >> a >> b;
--a; --b;
to[a].push_back(b);
to[b].push_back(a);
}
vector<int> d(n, -1);
priority_queue<P> q;
rep(i, k) {
int p, h;
cin >> p >> h;
--p;
d[p] = h;
q.emplace(h, p);
}
while (q.size()) {
auto [h, v] = q.top(); q.pop();
if (d[v] != h) continue;
for (int u : to[v]) {
if (d[u] >= h-1) continue;
d[u] = h-1;
q.emplace(h-1, u);
}
}
vector<int> ans;
rep(i, n) if (d[i] >= 0) ans.push_back(i+1);
cout << ans.size() << '\n';
for (int v : ans) cout << v << ' ';
return 0;
}
T6:Dungeon Explore
\(\operatorname{dfs}\) 树
为了不重复遍历同一个点,除了在死胡同中回头的时候,普通 \(\operatorname{dfs}\) 可以在 \(2N\) 次以内实现。
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<bool> used(n+1);
vector<int> pre(n+1);
auto get = [&]() {
int k;
cin >> k;
vector<int> res(k);
rep(i, k) cin >> res[i];
return res;
};
int v = 1;
used[v] = true;
while (v != n) {
auto to = get();
int u = -1;
for (int x : to) {
if (!used[x]) u = x;
}
if (u == -1) u = pre[v];
else {
used[u] = true;
pre[u] = v;
}
cout << u << '\n';
v = u;
}
return 0;
}
T7:Banned Substrings
记 dp[i][s] 表示长度为 \(i\) 且最后的 \(5\) 个字符构成的子串为 \(s\) 时的合法字符串个数
由于转移不依赖于 \(i\),所以可以用矩阵快速幂来优化!
时间复杂度为 \(\mathcal{O}(\log N \cdot M^3)\)
代码实现
#include <bits/stdc++.h>
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
#endif
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using mint = modint998244353;
template<typename T>
struct Matrix {
int h, w;
vector<vector<T>> d;
Matrix() {}
Matrix(int h, int w, T val=0): h(h), w(w), d(h, vector<T>(w,val)) {}
Matrix& unit() {
assert(h == w);
rep(i,h) d[i][i] = 1;
return *this;
}
const vector<T>& operator[](int i) const { return d[i];}
vector<T>& operator[](int i) { return d[i];}
Matrix operator*(const Matrix& a) const {
assert(w == a.h);
Matrix r(h, a.w);
rep(i,h)rep(k,w)rep(j,a.w) {
r[i][j] += d[i][k]*a[k][j];
}
return r;
}
Matrix pow(long long t) const {
assert(h == w);
if (!t) return Matrix(h,h).unit();
if (t == 1) return *this;
Matrix r = pow(t>>1);
r = r*r;
if (t&1) r = r*(*this);
return r;
}
};
int main() {
ll n; int m;
cin >> n >> m;
vector<string> S(m);
rep(i, m) cin >> S[i];
auto check = [&](int t, int w) {
string ts;
rep(i, w) ts += 'a'+(t&1), t >>= 1;
reverse(ts.begin(), ts.end());
for (string s : S) {
if (ts.find(s) != string::npos) return false;
}
return true;
};
int l = 5, d = 1<<l;
if (n < l) {
int ans = 0;
rep(i, 1<<n) {
if (check(i, n)) ans++;
}
cout << ans << '\n';
return 0;
}
Matrix<mint> a(d, d), x(1, d);
rep(i, d) {
rep(c, 2) {
int j = (i<<1)|c;
if (!check(j, l+1)) continue;
j &= d-1;
a[i][j] += 1;
}
}
rep(i, d) {
if (check(i, l)) x[0][i] = 1;
}
x = x*a.pow(n-l);
mint ans;
rep(i, d) ans += x[0][i];
cout << ans.val() << '\n';
return 0;
}
浙公网安备 33010602011771号