链接:https://codeforces.com/gym/104354
A. 小水獭游河南
使用 \(\text{hash}\),\(O(\sum n)\)。
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
constexpr int B = 114514;
constexpr i64 P = 1000000000039;
vector<i64> p;
void init(int N) {
p.assign(N, 0);
p[0] = 1;
for (int i = 1; i <= N; i++) {
p[i] = p[i - 1] * B % P;
}
}
struct StringHash {
vector<i64> h;
StringHash() : h(1) {}
void push_back(char ch) {
h.push_back((h.back() * B + ch) % P);
}
i64 toi64(int l, int r) { // [l, r)
return (h[r] + __int128(h[l]) * (P - p[r - l])) % P;
}
};
void solve() {
string s;
cin >> s;
int n = s.size();
StringHash hs;
for (int i = 0; i < n; i++) {
hs.push_back(s[i]);
}
StringHash rhs;
for (int i = n - 1; i >= 0; i--) {
rhs.push_back(s[i]);
}
vector<int> vis(26);
for (int i = 0; i < n - 1; i++) {
if (!vis[s[i] - 'a']) {
vis[s[i] - 'a'] = 1;
if (hs.toi64(i + 1, n) == rhs.toi64(0, n - i - 1)) {
cout << "HE\n";
return;
}
} else {
break;
}
}
cout << "NaN\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
init(1E5);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
B. Art for Rest
前缀最大和后缀最小,\(O(n)\)。
C++ Code
#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;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
int inf = 1E9;
vector<int> pre(n + 1), suf(n + 1, inf);
for (int i = 0; i < n; i++) {
pre[i + 1] = max(pre[i], a[i]);
}
reverse(a.begin(), a.end());
for (int i = 0; i < n; i++) {
suf[i + 1] = min(suf[i], a[i]);
}
reverse(suf.begin(), suf.end());
int ans = 0;
for (int i = 1; i <= n; i++) {
bool ok = 1;
for (int j = i; j <= n; j += i) {
if (pre[j] > suf[j]) {
ok = 0;
break;
}
}
ans += (ok == 1);
}
cout << ans << '\n';
return 0;
}
C. Toxel 与随机数生成器
\(\text{kmp}\),\(O(n)\)。
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s;
cin >> s;
int n = s.size();
vector<int> nex(n + 1);
for (int i = 1, j = 0; i < n; i++) {
while (j && s[i] != s[j]) {
j = nex[j];
}
if (s[i] == s[j]) {
j++;
}
nex[i + 1] = j;
}
for (int i = 0; i <= n; i++) {
if (nex[i] >= 1000) {
cout << "No\n";
return;
}
}
cout << "Yes\n";
return 0;
}
E. 矩阵游戏
dp,\(O(nmx)\)。
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
constexpr int N = 500;
constexpr int M = 1000;
int f[N + 1][M + 1];
void solve() {
int n, m, x;
cin >> n >> m >> x;
vector<string> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int i = 0; i <= m; i++) {
for (int j = 0; j <= x; j++) {
f[i][j] = 0;
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
for (int k = x; k >= 0; k--) {
f[j + 1][k] = max(f[j + 1][k], f[j][k]) + (a[i][j] == '1');
if (k && a[i][j] == '?') {
f[j + 1][k] = max(f[j + 1][k - 1], f[j][k - 1]) + 1;
}
}
}
}
cout << f[m][x] << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
F. Art for Last
使用 \(\text{ST}\) 表,\(O(n\log n)\),还有别的方法。
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
template <typename T>
struct SparseTable {
int n;
function<T(const T&, const T&)> func;
vector<vector<T>> a;
SparseTable(const vector<T> &init, const function<T(const T&, const T&)> &f) : n(init.size()), func(f) {
int lg = __lg(n);
a.assign(lg + 1, vector<T>(n));
a[0] = init;
for (int i = 1; i <= lg; i++) {
for (int j = 0; j <= n - (1 << i); j++) {
a[i][j] = func(a[i - 1][j], a[i - 1][(1 << (i - 1)) + j]);
}
}
}
T get(int l, int r) {// [l, r)
int lg = __lg(r - l);
return func(a[lg][l], a[lg][r - (1 << lg)]);
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, k;
cin >> n >> k;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
auto b = a;
sort(b.begin(), b.end());
vector<int> c(n - 1);
for (int i = 0; i < n - 1; i++) {
c[i] = b[i + 1] - b[i];
}
auto Min = [&](const int &a, const int &b) {
return min(a, b);
};
SparseTable<int> mn(c, Min);
i64 ans = 1E18;
for (int i = 0; i + k - 1 < n; i++) {
int x = b[i + k - 1] - b[i];
int y = mn.get(i, i + k - 1);
ans = min(ans, 1LL * x * y);
}
cout << ans << '\n';
return 0;
}
G. Toxel 与字符画
模拟。
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
using i128 = __int128;
constexpr i64 inf = 1E18;
i64 mul(i64 a, i64 b) {
i128 res = static_cast<i128>(a) * b;
if (res > inf) {
return inf + 1;
}
return res;
}
i64 power(i64 a, i64 b) {
i64 res = 1;
for (; b; b >>= 1, a = mul(a, a)) {
if (b & 1) {
res = mul(res, a);
}
}
return res;
}
vector<string> a = {
"................................................................................",
"................................................................................",
"0000000.......1.2222222.3333333.4.....4.5555555.6666666.7777777.8888888.9999999.",
"0.....0.......1.......2.......3.4.....4.5.......6.............7.8.....8.9.....9.",
"0.....0.......1.......2.......3.4.....4.5.......6.............7.8.....8.9.....9.",
"0.....0.......1.2222222.3333333.4444444.5555555.6666666.......7.8888888.9999999.",
"0.....0.......1.2.............3.......4.......5.6.....6.......7.8.....8.......9.",
"0.....0.......1.2.............3.......4.......5.6.....6.......7.8.....8.......9.",
"0000000.......1.2222222.3333333.......4.5555555.6666666.......7.8888888.9999999.",
"................................................................................"
};
vector<string> b = {
"............................................................",
"00000.....1.22222.33333.4...4.55555.66666.77777.88888.99999.",
"0...0.....1.....2.....3.4...4.5.....6.........7.8...8.9...9.",
"0...0.....1.22222.33333.44444.55555.66666.....7.88888.99999.",
"0...0.....1.2.........3.....4.....5.6...6.....7.8...8.....9.",
"00000.....1.22222.33333.....4.55555.66666.....7.88888.99999.",
"............................................................",
"............................................................",
"............................................................",
"............................................................"
};
vector<string> c = {
"................................",
"................................",
"........IIIIIII.N.....N.FFFFFFF.",
"...........I....NN....N.F.......",
"=======....I....N.N...N.F.......",
"...........I....N..N..N.FFFFFFF.",
"=======....I....N...N.N.F.......",
"...........I....N....NN.F.......",
"........IIIIIII.N.....N.F.......",
"................................"
};
void solve() {
i64 A, B;
scanf("%lld^{%lld}", &A, &B);
int N = 10;
i64 res = power(A, B);
vector<string> ans(N);
for (int i = 0; i < N; i++) {
ans[i] += ".";
}
auto get = [&](const int &l, const int &len, const vector<string> &s) {
for (int i = 0; i < N; i++) {
ans[i] += s[i].substr(l, len);
}
};
string SA = to_string(A);
string SB = to_string(B);
for (auto &x : SA) {
int y = x - '0';
get(y * 8, 8, a);
}
for (auto &x : SB) {
int y = x - '0';
get(y * 6, 6, b);
}
get(0, 8, c);
if (res > inf) {
get(8, 24, c);
} else {
string t = to_string(res);
for (auto &x : t) {
int y = x - '0';
get(y * 8, 8, a);
}
}
for (auto &x : ans) {
cout << x << '\n';
}
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
solve();
}
return 0;
}
H. Travel Begins
贪心,\(O(t)\)。
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
void solve() {
int n, k;
cin >> n >> k;
int cnt = min(n * 2, k - 1);
int ans2 = n - cnt / 2 + cnt;
int ans1 = max(0, n - cnt / 2);
cout << ans1 << ' ' << ans2 << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
J. Mocha 沉迷电子游戏
计算几何,分两种情况,\(O(t)\)。
C++ Code
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
using Real = double;
using Point = complex<Real>;
const double Pi = acos(-1.0);
void solve() {
int x, y;
cin >> x >> y;
Point p = Point(x, y);
cin >> x >> y;
Point a = Point(x, y);
cin >> x >> y;
Point b = Point(x, y);
int v, t;
cin >> v >> t;
int r = v * t;
Point c = (a + b) / 2.0;
const double pa = abs(p - a);
const double pc = abs(p - c);
const double ab = abs(a - b);
double ans = 0;
const double ad = sqrt(pa * pa - 1LL * r * r);
if (r > pa) {
cout << Pi * r * r << '\n';
return;
}
if (r <= pc) {
ans += ad * r;
ans += pc * ab / 2;
double ang = asin(ad / pa) + asin(ab / 2 / pa);
ans += (Pi - ang) * r * r;
} else {
ans += ad * r * 2;
double ang = asin(ad / pa);
ans += (Pi - 2 * ang) * r * r;
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout << fixed << setprecision(15);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
K. 排列与质数
小的全排列,大的构造,\(O(n)\)。
C++ Code
#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;
if (n < 5) {
cout << -1 << '\n';
return 0;
}
if (n == 5) {
cout << "1 3 5 2 4\n";
return 0;
}
if (n == 6) {
cout << "1 3 5 2 4 6\n";
return 0;
}
if (n == 7) {
cout << "1 3 5 2 7 4 6\n";
return 0;
}
if (n == 8) {
cout << "1 3 5 2 7 4 6 8\n";
return 0;
}
if (n == 9) {
cout << "1 3 5 2 4 7 9 6 8\n";
return 0;
}
if (n == 10) {
cout << "1 3 5 2 4 6 9 7 10 8\n";
return 0;
}
if (n == 11) {
cout << "1 3 5 2 4 6 11 9 7 10 8\n";
return 0;
}
vector<int> ans;
if (n % 2 == 0) {
for (int i = 1; i < n - 1; i += 2) {
ans.push_back(i);
if (i == 5) {
ans.push_back(2);
}
}
for (int i = n; i >= 3; i -= 2) {
ans.push_back(i);
if (i == n - 4) {
ans.push_back(n - 1);
}
}
} else {
for (int i = 1; i <= n; i += 2) {
ans.push_back(i);
if (i == 5) {
ans.push_back(2);
}
if (i == n - 6) {
ans.push_back(n - 1);
}
}
for (int i = n - 3; i >= 4; i -= 2) {
ans.push_back(i);
}
}
for (int i = 0; i < n; i++) {
cout << ans[i] << " \n"[i == n - 1];
}
return 0;
}
- Programming Collegiate Provincial Contest Henanprogramming collegiate provincial contest programming collegiate provincial shandong programming provincial collegiate sichuan programming collegiate provincial guangdong programming provincial collegiate shandong programming collegiate provincial counting programming provincial collegiate sponsored 2023 programming collegiate provincial 题解programming collegiate provincial programming collegiate jiangsu contest