• A - Rock-paper-scissors">A - Rock-paper-scissors
  • B - Nuts">B - Nuts
  • C - Tour">C - Tour
  • D - Cooking">D - Cooking
  • E - Rush Hour 2">E - Rush Hour 2

    补题链接:Here

    A - Rock-paper-scissors

    石头剪刀布,两方是一样的则输出该值,否则输出该值

    1. int s[4] = {0, 1, 2};
    2. void solve() {
    3. int x, y;
    4. cin >> x >> y;
    5. if (x == y) cout << x;
    6. else {
    7. for (int i = 0; i < 3; i++)
    8. if (s[i] != x && s[i] != y)
    9. cout << s[i];
    10. }
    11. }

    B - Nuts

    坚果数超过 AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图1 个便累加(x-10)

    1. void solve() {
    2. int n;
    3. cin >> n;
    4. int cnt = 0;
    5. for (int i = 0, x; i < n; ++i) {
    6. cin >> x;
    7. if (x > 10)cnt += (x - 10);
    8. }
    9. cout << cnt;
    10. }

    C - Tour

    AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图2 个城市,AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图3 条单向道路,请问在以每个城市为起点能有多少个终点(本身也算


    AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图4 ,DFS 在图上搜索即可

    1. const int N = 2e3 + 10;
    2. vector<int>e[N];
    3. bool vis[N];
    4. void dfs(int u) {
    5. if (vis[u])return ;
    6. vis[u] = true;
    7. for (int v : e[u])dfs(v);
    8. }
    9. void solve() {
    10. int n, m; cin >> n >> m;
    11. while (m--) {
    12. int a, b; cin >> a >> b;
    13. e[a].push_back(b);
    14. }
    15. int ans = 0;
    16. for (int i = 1; i <= n; ++i) {
    17. memset(vis, false, sizeof(vis));
    18. dfs(i);
    19. for (int j = 1; j <= n; ++j)if (vis[j])ans++;
    20. }
    21. cout << ans;
    22. }

    D - Cooking

    两个微波炉,AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图5 道菜,每个菜需要 AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图6 分钟加热,请问最少需要多少时间才能把所有菜都加热完毕


    烤箱的使用顺序无关紧要;只有为每道菜指定一个烤箱才是必要的。
    考虑到根据要分配的两个烤箱中的哪一个将菜分为两组,该问题等价于“将N个菜分为两组,使烹调菜所需的最大次数之和最小化。”设为 AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图7。我们可以假设第一个烤箱的占用时间不少于第二个烤箱的占用时间(如果不是,我们可以交换这两个烤箱)。然后,第一烤箱的使用持续时间至少为 AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图8 。由于我们想在这个约束条件下尽可能减少使用第一台烤箱的时间,所以问题归结为“AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图9的子集的最小和大于或等于 AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图10 是多少?”如果我们能为每个x回答“ AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图11的子集是否存在,这只不过是一个子集和问题,所以它可以在 AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图12#card=math&code=%5Cmathcal%7BO%7D%28N%5Csum_iT_i%29&id=ullYy) 的总和中找到∑ 具有以下布尔值的DP

    1. bitset<100004>f;
    2. void solve() {
    3. int n; cin >> n;
    4. int cnt = 0;
    5. f[0] = 1;
    6. for (int i = 0, x; i < n; ++i) {
    7. cin >> x;
    8. f |= f << x; cnt += x;
    9. }
    10. int ans = 1e9;
    11. for (int i = 0; i < 1e5; ++i)if (f[i])ans = min(ans, max(i, cnt - i));
    12. cout << ans;
    13. }

    E - Rush Hour 2

    AtCoder王国有 AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图13 个城市和 AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图14 条双向道路

    假设在 AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图15 时刻经过了第 AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图16 条道路,则通过的时间为 AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图17

    现在请问最短的时间是多少,Takahashi 可以从城市 AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图18 到达城市 AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图19 ,如果到达不了则输出 AtCoder Beginner Contest 204 (AB水题,C题DFS,D题位运算DP,E题BFS好题) - 图20


    利用优先队列跑 BFS,同时用 tuple 元组存储数据 (记得开启 C++17 来保证 tuple 可通过编译)

    1. #define inf 9223372036854775807LL
    2. #define N 100005
    3. using ll = long long;
    4. using Edge = tuple<int, int, int>;
    5. using pli = pair<ll, int>;
    6. vector<Edge> e[N];
    7. ll dist[N];
    8. void solve() {
    9. int n, m;
    10. cin >> n >> m;
    11. while (m--) {
    12. int a, b, c, d;
    13. cin >> a >> b >> c >> d;
    14. if (--a == --b)continue;
    15. e[a].emplace_back(b, c, d);
    16. e[b].emplace_back(a, c, d);
    17. }
    18. dist[0] = 0LL;
    19. for (int i = 1; i < n; i++) dist[i] = inf;
    20. priority_queue<pli, vector<pli>, greater<pli>>q;
    21. q.emplace(0, 0);
    22. while (!q.empty()) {
    23. auto [t, u] = q.top();
    24. q.pop();
    25. if (dist[u] != t)continue;
    26. for (auto [v, c, d] : e[u]) {
    27. ll t2 = sqrt((long double) d) - 0.5;
    28. if (t2 < t) t2 = t;
    29. t2 += ll(c) + ll(d) / (t2 + 1ll);
    30. if (t2 < dist[v])
    31. q.emplace(dist[v] = t2, v);
    32. }
    33. }
    34. cout << (dist[n - 1] == inf ? -1 : dist[n - 1]) << endl;
    35. }