https://zhuanlan.zhihu.com/p/681154402
A
。
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
void solve() {
int n;
string s;
cin >> n >> s;
string t[] = {"DFS", "dfs"};
for (int i = 0; i < 2; i++) {
int k = 0;
for (int j = 0; j < n && k < 3; j++) {
if (t[i][k] == s[j]) {
k++;
}
}
cout << (k == 3) << " \n"[i == 1];
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
B
答案最大为 ,最坏的情况是堵住 。
表示的是阻止鸡到左边需要添加的着火点, 表示的是阻止鸡到右边需要添加的着火点。
。
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
void solve() {
int n;
cin >> n;
set<pair<int, int>> s;
int ans0 = 2, ans1 = 2;
for (int i = 0; i < n; i++) {
int r, c;
cin >> r >> c;
s.insert({r, c});
if (c <= 0) {
ans0 = 1;
}
if (c >= 0) {
ans1 = 1;
}
}
for (auto [r, c] : s) {
for (int i = -1; i < 2; i++) {
if (s.count({r ^ 3, c + i})) {
if (c < 0) {
ans0 = 0;
}
if (c > 0) {
ans1 = 0;
}
}
}
}
int ans = 3 - s.count({2, 0}) - s.count({1, -1}) - s.count({1, 1});
cout << min(ans, ans0 + ans1) << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
C
小的排前面。
贪心,前缀和。
#include "bits/stdc++.h"
#define range(a) begin(a), end(a)
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, q, tc;
cin >> n >> q >> tc;
vector<int> t(n);
for (int i = 0; i < n; i++) {
cin >> t[i];
}
sort(range(t));
vector<i64> sum(n + 1);
for (int i = 0; i < n; i++) {
sum[i + 1] = sum[i] + t[i];
}
while (q--) {
i64 m;
cin >> m;
int c = min(i64(n), m / tc);
cout << sum[n - c] + tc << '\n';
}
return 0;
}
D
分解为若干个不同的数的乘积,不大于 个。
把所有有可能的数存到 里,设为 个。
。
#include "bits/stdc++.h"
#define range(a) begin(a), end(a)
using namespace std;
using i64 = long long;
constexpr int K = 4E4;
constexpr int inf = 1E9 + 1;
int power(int a, int b) {
int res = 1;
for (; b; b >>= 1) {
if (b & 1) {
if (abs(i64(res) * a) > inf) {
return inf;
}
res *= a;
}
if (abs(i64(a) * a) > inf) {
a = inf;
} else {
a *= a;
}
}
return res;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, q;
cin >> n >> q;
vector<int> a(n);
map<int, int> cnt;
for (int i = 0; i < n; i++) {
cin >> a[i];
cnt[a[i]]++;
}
sort(range(a));
a.erase(unique(range(a)), a.end());
int N = a.size();
set<int> s{0};
if (N <= 20) {
for (int i = 0; i < N; i++) {
for (int k = -K - a[i]; k <= K - a[i]; k++) {
int res = 1;
for (int j = 0; j < N; j++) {
int x = a[j] + k, y = cnt[a[j]];
int v = power(x, y);
if (abs(i64(res) * v) > inf) {
res = inf;
break;
}
res *= v;
}
if (abs(res) < inf) {
s.insert(res);
}
}
}
}
while (q--) {
int m;
cin >> m;
cout << (s.count(m) ? "Yes" : "No") << '\n';
}
return 0;
}
E
类似于子集枚举,也可以使用 。
。
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
void solve() {
int n, m;
cin >> n >> m;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
vector<pair<int, int>> b(m);
for (int i = 0; i < m; i++) {
auto &[u, v] = b[i];
cin >> u >> v;
u--, v--;
}
int K = 1;
for (int i = 0; i < m; i++) {
K *= 3;
}
int ans = n;
for (int mask = 0; mask < K; mask++) {
auto c = a;
for (int i = 0, x = mask; i < m; i++, x /= 3) {
auto [u, v] = b[i];
if (x % 3 == 0) {
c[u] += 3;
} else if (x % 3 == 1) {
c[v] += 3;
} else {
c[u]++, c[v]++;
}
}
int k = 1;
for (int i = 1; i < n; i++) {
k += (c[i] > c[0]);
}
ans = min(ans, k);
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
F
问题转变为 个不同的小球放在 个相同的箱子里,求方案数,这是第二类斯特林数。
预处理组合数。
。
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
constexpr int P = 1000000007;
i64 *fac, *ifac;
i64 power(i64 a, i64 b, int p = P) {
i64 res = 1;
for (; b; b >>= 1, a = a * a % p) {
if (b & 1) {
res = res * a % p;
}
}
return res;
}
i64 inv(i64 x) {
return power(x, P - 2);
}
void init(int N) {
fac = new i64 [N + 1];
ifac = new i64 [N + 1];
fac[0] = 1;
for (int i = 1; i <= N; i++) {
fac[i] = fac[i - 1] * i % P;
}
ifac[N] = inv(fac[N]);
for (int i = N - 1; i >= 0; i--) {
ifac[i] = ifac[i + 1] * (i + 1) % P;
}
}
i64 C(int n, int m) {
if (m < 0 || m > n || n < 0) {
return 0;
}
return fac[n] * ifac[m] % P * ifac[n - m] % P;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
init(m);
i64 ans = 0;
for (int k = 0; k <= m; k++) {
if (k % 2 == 0) {
ans = (ans + C(m, k) * power(m - k, n) % P) % P;
} else {
ans = (ans - C(m, k) * power(m - k, n) % P + P) % P;
}
}
cout << ans * ifac[m] % P << '\n';
return 0;
}
G
前缀和。
。
#include "bits/stdc++.h"
#define range(a) begin(a), end(a)
using namespace std;
using i64 = long long;
void solve() {
int n, m;
cin >> n >> m;
vector<pair<int, int>> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i].first >> a[i].second;
}
sort(range(a));
vector<i64> sum(n + 1);
for (int i = 0; i < n; i++) {
sum[i + 1] = sum[i] + a[i].second;
}
i64 ans = m;
for (int i = 0; i < n; i++) {
if (a[i].first - sum[i + 1] <= m) {
ans = sum[i + 1] + m;
}
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
H
位运算,考虑小于等于 的数的二进制 的位。
。
。
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
void solve() {
int n, m;
cin >> n >> m;
vector<int> v(n), w(n);
for (int i = 0; i < n; i++) {
cin >> v[i] >> w[i];
}
auto get = [&](int x) {
i64 res = 0;
for (int i = 0; i < n; i++) {
if ((x & w[i]) == w[i]) {
res += v[i];
}
}
return res;
};
i64 ans = get(m);
for (int i = m; i; i -= i & -i) {
ans = max(ans, get(i - 1));
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
I
第一种生成的圆的圆心会更加分散,并且每个区域会更加平均。第二种生成的圆的圆心会更加靠近中间。
圆心会落在 。
那么我们只要取一个中间区域的圆心数量,就可以判断是第一种还是第二种。
圆心 , 都在 的概率为 ,略取大一点 ,。
。
#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;
int ans = 0;
for (int i = 0; i < n; i++) {
int x, y, r;
cin >> x >> y >> r;
if (x <= 9 && x >= -9 && y <= 9 && y >= -9) {
ans++;
}
}
if (ans <= n / 90) {
cout << "bit-noob\n";
} else {
cout << "buaa-noob\n";
}
return 0;
}
K
置换环。
。
#include "bits/stdc++.h"
#define range(a) begin(a), end(a)
using namespace std;
using i64 = long long;
constexpr int P = 998244353;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> a(n);
vector<string> s(n);
for (int i = 0; i < n; i++) {
cin >> a[i] >> s[i];
a[i]--;
}
i64 ans = 1;
vector<int> vis(n);
for (int i = 0; i < n; i++) {
int j = i;
vector<int> c;
for (; !vis[j]; j = a[j]) {
vis[j] = 1;
c.push_back(j);
}
auto it = find(range(c), j);
if (it != c.end()) {
c.erase(c.begin(), it);
int res = 0;
for (char st = 'A'; st < 'F'; st++) {
char cur = st;
for (auto x : c) {
cur = s[x][cur - 'A'];
}
res += (cur == st);
}
ans = ans * res % P;
}
}
cout << ans << '\n';
return 0;
}
L
算梯形面积。
。
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
void solve() {
int c, d, h, w;
cin >> c >> d >> h >> w;
cout << 3LL * w * c << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
M
。
#include "bits/stdc++.h"
using namespace std;
using i64 = long long;
void solve() {
int n;
cin >> n;
if (n % 6 == 0) {
cout << n / 6 << '\n';
} else {
cout << n / 6 * 2 << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}