2026/1/17-Atcoder Beginner Contest 441 T1~5
前言
比赛的时候只写了A~E后面结束后补,比赛链接:Atcoder 441
致力于把题目用通俗的语言翻译出来,让新人也能看懂
A
只要X Y范围在 (P,Q) 和 (P+99,Q+99)范围之间就成立
B
只要分成两个集合A,B
字符串中每一个字符都去匹配一下集合A,B就行了
C
题目人话:
有 N 个杯子,每个杯子里装了 Ai 毫升液体(比如杯子 1 装 10 毫升,杯子 2 装 8 毫升);
这 N 个杯子里,恰好有 K 个装的是清酒(剩下的都是水);
你不知道哪 K 个是清酒,只能盲选一些杯子(至少选 1 个);
要求:不管清酒藏在哪些杯子里,你选的这些杯子里的清酒总量,都至少有 X 毫升;
你的目标:找到满足要求的最少杯子数量;如果怎么选都做不到,就输出 - 1。
写题分析:
一,最坏情况
我们拿取杯子一定要按最坏情况来算,即清酒尽可能多的藏在没选的杯子里,且选中的杯子里的清酒都是容量小的那些,这样喝到的清酒才最少。
二,贪心策略
对于上面发生最坏情况,接下来是我们来选杯子,所以我们选杯子一定要从大往小选,即把杯子按照容量从大到小排序,接下来分三个大白话公式,假设选择m个杯子:
1,没选的杯子=总杯子N-选的数量m;
2,没选的杯子里的清酒=最多藏 min(K, 没选的杯子数) 杯
3,所以 选的杯子里的清酒 = K - 没选的杯子藏的清酒数
选的杯子中最小的那些杯数就是清酒的,累加这个容量和为sum;清酒杯数小于0则sum=0
三,枚举选择的杯数,前缀和优化
我们从小到大枚举杯子数量 m ,通过前缀和快速计算出喝到的清酒容量 sum ,再与 X 毫升判断;因为m从小到大,一找到就break。
代码:
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define int long long
#define eb emplace_back
#define all(x) (x).begin(), (x).end()
void solve()
{
int n, k, x;
cin >> n >> k >> x;
vector<int> cup(n);
for (int i = 0; i < n; i++)
{
cin >> cup[i];
}
sort(all(cup), greater<int>());
vector<int> pre(n + 1, 0);
for (int i = 0; i < n; i++)
{
pre[i + 1] = pre[i] + cup[i];
}
int ans = -1;
for (int m = 1; m <= n; m++)
{
int s = min(k, n - m);
int t = k - s;
int wor = 0;
if (t > 0)//杯子小于0的一律达斯
{
wor = pre[m] - pre[m - t];
}
if (wor >= x)//小于x毫升的也达斯
{
ans = m;
break;
}
}
cout << ans << "\n";
}
signed main()
{
IOS;
solve();
return 0;
}
D
题目人话
地图上有 N 个地点(顶点),编号 1、2、…、N;
地点之间有 M 条 “单向路”(边),比如从地点 1 到地点 2 的路,走一次要花 20 “路费”(代价 C);
每个地点最多只有 4 条往外走的路(出度≤4);
从地点 1 出发,走恰好 L 步(每走一条路算 1 步,重复走同一条路也算步数);
要求走这 L 步的总路费,必须在 S 到 T 之间(比如 80≤总路费≤100);
找出所有满足条件的 “终点”(走到 L 步时停在哪个地点);
最后把这些终点按从小到大的顺序输出,没有就输出空行。
解题分析
1,观察题目
注意数据范围:1≤L≤10,走10步每一步最多4种选择,一共有410=1048576 ,所以可以用暴力枚举的方法来写。
2,实现分析
1,我们可以用dfs来完成这个题目,遇到满足直接加入dfs写法
2,我们还可以用动态规划的递推思想来完成这个题,设dp[k][u]=从点1出发,恰好走k步,到达地点u的所有路费方案的集合。递推方程为 dp[k-1][u]中沿着u的出边走一步的所有路费方案所构成集合 = dp[k]
代码
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define int long long
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(), (x).end()
using ll = long long;
using pii = pair<int, int>;
using pil = pair<int, long long>;
const int INF = 0x3f3f3f3f;
const int MAXN = 2e5 + 10;
vector<vector<pii>> g(MAXN);
vector<unordered_map<int, unordered_set<ll>>> dp;
void solve()
{
int n, m, L, S, T;
cin >> n >> m >> L >> S >> T;
for (int i = 0; i < m; i++)
{
int u, v, c;
cin >> u >> v >> c;
g[u].eb(v, c);
}
dp.resize(L + 1);
dp[0][1].insert(0);
for (int k = 0; k < L; k++)
{
for (auto &[u, sum_set] : dp[k])
{
for (auto &[v, c] : g[u])
{
for (ll s : sum_set)
{
ll new_sum = s + c;
if (new_sum > T)
continue;
dp[k + 1][v].insert(new_sum);
}
}
}
}
vector<int> ans;
for (auto &[v, sum_set] : dp[L])
{
for (ll s : sum_set)
{
if (s >= S && s <= T)
{
ans.pb(v);
break;
}
}
}
sort(all(ans));
for (int i = 0; i < ans.size(); i++)
{
if (i > 0)
cout << " ";
cout << ans[i];
}
cout << "\n";
}
signed main()
{
IOS;
int T;
T = 1;
while (T--)
{
solve();
}
return 0;
}
E
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define int long long
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(), (x).end()
using ll = long long;
using pii = pair<int, int>;
using pil = pair<int, long long>;
const int INF = 0x3f3f3f3f;
const int MAXN = 5e5 + 10;
const int OFFSET = 5e5 + 5;
struct BIT
{
vector<int> tree;
int size;
BIT(int n) : size(n), tree(n + 1, 0) {}
void update(int pos, int val = 1)
{
for (; pos <= size; pos += pos & -pos)
{
tree[pos] += val;
}
}
int query(int pos)
{
int res = 0;
for (; pos > 0; pos -= pos & -pos)
{
res += tree[pos];
}
return res;
}
};
void solve()
{
int n;
string s;
cin >> n >> s;
vector<int> pre(n + 1, 0);
for (int i = 1; i <= n; i++)
{
if (s[i - 1] == 'A')
pre[i] = pre[i - 1] + 1;
else if (s[i - 1] == 'B')
pre[i] = pre[i - 1] - 1;
else
pre[i] = pre[i - 1];
}
vector<int> tmp = pre;
sort(all(tmp));
tmp.erase(unique(all(tmp)), tmp.end());
int fen_size = tmp.size();
BIT ft(fen_size);
int idx0 = lower_bound(all(tmp), pre[0]) - tmp.begin() + 1;
ft.update(idx0);
int ans = 0;
for (int r = 1; r <= n; r++)
{
int pos = lower_bound(all(tmp), pre[r]) - tmp.begin();
ans += ft.query(pos);
int idx = lower_bound(all(tmp), pre[r]) - tmp.begin() + 1;
ft.update(idx);
}
cout << ans << "\n";
}
signed main()
{
IOS;
int T = 1;
// cin >> T;
while (T--)
{
solve();
}
return 0;
}

浙公网安备 33010602011771号