首页 > 其他分享 >AtCoder Beginner Contest 327

AtCoder Beginner Contest 327

时间:2023-11-04 21:58:39浏览次数:39  
标签:AtCoder Beginner int auto cin long 327 tie using

A - ab (abc327 A)

题目大意

给定一个字符串\(s\),问是否包含 abba

解题思路

遍历判断即可。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    string s;
    cin >> n >> s;
    bool ok = false;
    for (int i = 1; i < n; ++i) {
        ok |= (s[i] == 'a' && s[i - 1] == 'b');
        ok |= (s[i - 1] == 'a' && s[i] == 'b');
    }
    if (ok)
        cout << "Yes" << '\n';
    else
        cout << "No" << '\n';

    return 0;
}



B - A^A (abc327 B)

题目大意

给定\(b\),问是否存在 \(a\)使得 \(a^a = b\)。

解题思路

由于指数爆炸的缘故,\(a\)的范围不会很大,枚举\(a\),看\(b \% a\)是否为 \(0\),然后用\(b\)不断除以 \(a\) ,看最后除的次数是否等于\(a\)。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    LL b;
    cin >> b;
    int ans = -1;
    for (int i = 2; i <= 20; ++i) {
        if (b % i != 0)
            continue;
        LL x = b;
        int cnt = 0;
        while (x > 1) {
            x /= i;
            ++cnt;
        }
        if (cnt == i) {
            ans = i;
            break;
        }
    }
    if (b == 1)
        ans = 1;
    cout << ans << '\n';

    return 0;
}



C - Number Place (abc327 C)

题目大意

给定一个\(9 \times 9\)的网格,问是否符合数独局面。

数独局面,即每行 \(1-9\),每列 \(1-9\),每个 \(3 \times 3\)的格子有 \(1-9\)。

解题思路

按照条件,逐行、逐列、逐格子分别判断即可。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    array<array<int, 9>, 9> a;
    for (auto& i : a)
        for (auto& j : i)
            cin >> j;
    auto ok = [&]() {
        for (auto& i : a) {
            if (set<int>(i.begin(), i.end()).size() != 9)
                return false;
        }
        for (int i = 0; i < 9; ++i) {
            set<int> cnt;
            for (int j = 0; j < 9; ++j) {
                cnt.insert(a[j][i]);
            }
            if (cnt.size() != 9)
                return false;
        }
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 3; ++j) {
                set<int> cnt;
                for (int x = 0; x < 3; ++x)
                    for (int y = 0; y < 3; ++y) {
                        cnt.insert(a[i * 3 + x][j * 3 + y]);
                    }
                if (cnt.size() != 9)
                    return false;
            }
        }
        return true;
    };
    if (ok())
        cout << "Yes" << '\n';
    else
        cout << "No" << '\n';

    return 0;
}



D - Good Tuple Problem (abc327 D)

题目大意

给定两个数组长度为\(m\),仅包含\(1-n\)的\(a,b\),问它们是否是一对好数组。

若两个数组是一对好数组,则存在一个长度为\(n\)的\(01\)数组 \(x\),使得 \(x_{a_i} \neq x_{b_i}, \forall i \in [1, m]\)。

解题思路

将条件抽象成图,相当于是点\(a_i\)和点\(b_i\)连一条边,它们的颜色不能相同。

即最后是否是一张二分图,黑白染色即可。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    vector<int> a(m), b(m);
    for (auto& i : a) {
        cin >> i;
        --i;
    }
    for (auto& i : b) {
        cin >> i;
        --i;
    }
    vector<vector<int>> edge(n);
    for (int i = 0; i < m; ++i) {
        edge[a[i]].push_back(b[i]);
        edge[b[i]].push_back(a[i]);
    }
    vector<int> col(n, -1);
    bool ok = true;
    auto BFS = [&](int st) {
        queue<int> team;
        team.push(st);
        col[st] = 0;
        while (!team.empty()) {
            int u = team.front();
            team.pop();
            int target = (col[u] ^ 1);
            for (auto& v : edge[u]) {
                if (col[v] == -1) {
                    col[v] = target;
                    team.push(v);
                } else if (col[v] != target) {
                    ok = false;
                    return;
                }
            }
        }
    };
    for (int i = 0; i < n && ok; ++i) {
        if (col[i] == -1)
            BFS(i);
    }
    if (ok)
        cout << "Yes" << '\n';
    else
        cout << "No" << '\n';

    return 0;
}



E - Maximize Rating (abc327 E)

题目大意

给定\(n\)场比赛的表现分\(p_i\),现在选择一些场比赛,使得这些场比赛的 \(rating\)最大。

如果选择了 \(k\)场比赛 \((q_1, q_2, ..., q_k)\),则 \(rating\)为

\[\frac{\sum_{i=1}^{k}(0.9)^{k-i}q_i}{\sum_{i=1}^{k}(0.9)^{k-i}} - \frac{1200}{\sqrt{k}} \]

注意这里的\(q\)要按照原来的顺序排列。

解题思路

枚举\(k\),有几项就变成常数,唯一的变数就是最大化\(\sum_{i=1}^{k}(0.9)^{k-i}q_i\),这其实就是个经典的背包问题。

设\(dp[i][j]\)表示前 \(i\)场比赛,我选择了\(j\)场的\(\sum_{i=1}^{k}(0.9)^{k-i}q_i\)的最大值。

转移就是考虑当前比赛选或不选,则\(dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] * 0.9 + p_i)\)

初始条件就是\(dp[0][0] = 0\)。

答案就是\(\max(\frac{dp[n][k]}{\sum_{i=1}^{k}(0.9)^{k-i}} - \frac{1200}{\sqrt{k}})\)

时间复杂度是\(O(n^2)\)

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

const double inf = numeric_limits<double>::max();

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    vector<double> dp(n + 1, -inf);
    dp[0] = 0;
    for (int i = 0; i < n; ++i) {
        vector<double> dp2 = dp;
        int p;
        cin >> p;
        for (int j = 1; j <= i + 1; ++j) {
            dp2[j] = max(dp2[j], dp[j - 1] * 0.9 + p);
        }
        dp2.swap(dp);
    }
    double ans = -inf;
    double bottom = 1;
    for (int i = 1; i <= n; ++i) {
        ans = max(ans, dp[i] / bottom - 1200 / sqrt(i));
        bottom = bottom * 0.9 + 1;
    }
    cout << fixed << setprecision(10) << ans << '\n';

    return 0;
}



F - Apples (abc327 F)

题目大意

二维平面,给定若干个点,问一个长宽为\(d \times w\)的矩形所能覆盖的点的数量的最大值。

解题思路

枚举一个维度\(i\)(时间),问题就是在\([i, i + d)\)的范围内的另一维度(地点)的宽度为\(w\)的点数的最大值。

设数组\(a[i]\)表示 \(sum[i, i + w)\),即当前时间范围内的一个区间的点数,随着时间的流逝,会有新的点加入,会有旧的点删去。其影响的都是一个长度为 \(w\)的\(a\)区间,用线段树维护这个数组 \(a\)即可。

时间复杂度为\(O(n\log n)\)

神奇的代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;

const int N = 2e5 + 8;

class segtree {
#define lson (root << 1)
#define rson (root << 1 | 1)

    int max[N << 2], lazy[N << 2];

    inline void pushdown(int root) {
        if (lazy[root]) {
            lazy[lson] += lazy[root];
            max[lson] += lazy[root];
            lazy[rson] += lazy[root];
            max[rson] += lazy[root];
            lazy[root] = 0;
        }
    }

    void update(int root, int l, int r, int L, int R, LL val) {
        if (L <= l && r <= R) {
            lazy[root] += val;
            max[root] += val;
            return;
        }
        pushdown(root);
        int mid = (l + r) >> 1;
        if (L <= mid)
            update(lson, l, mid, L, R, val);
        if (R > mid)
            update(rson, mid + 1, r, L, R, val);
        max[root] = std::max(max[lson], max[rson]);
    }

    int query(int root, int l, int r) { return max[root]; }

  public:
    int n;
    void update(int L, int R, LL val) { update(1, 1, n, L, R, val); }

    int query() { return query(1, 1, n); }
};

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, d, w;
    cin >> n >> d >> w;
    vector<array<int, 2>> apple(n);
    for (auto& i : apple)
        cin >> i[0] >> i[1];
    vector<int> id(n);
    iota(id.begin(), id.end(), 0);
    ranges::sort(id, [&](int a, int b) { return apple[a][0] < apple[b][0]; });
    segtree seg;
    seg.n = N - 8;
    auto it = id.begin();
    int ans = 0;
    for (auto& i : id) {
        while (it != id.end() && apple[*it][0] + d <= apple[i][0]) {
            seg.update(max(1, apple[*it][1] - w + 1), apple[*it][1], -1);
            it = next(it);
        }
        seg.update(max(1, apple[i][1] - w + 1), apple[i][1], 1);
        ans = max(ans, seg.query());
    }
    cout << ans << '\n';

    return 0;
}



G - Many Good Tuple Problems (abc327 G)

题目大意

若两个数组是一对好数组,则存在一个长度为\(n\)的\(01\)数组 \(x\),使得 \(x_{a_i} \neq x_{b_i}, \forall i \in [1, m]\)。

问所有的长度为\(m\),仅包含 \(1-n\)的共 \(n^{2m}\)对数组中,好数组的数量。

解题思路

注意到一对数组是好数组,我们将每一位的数字连一条边,这意味着它们所形成的图是一张二分图。

考虑对这个二分图计数。

首先枚举左边部分的点的数量\(k\),注意到点取值多少不影响结果,因此方案数有 \(C_n^k\)。

然后考虑连边情况,每一条边都是从左边\(k\)个点选一个点,右边 \(n-k\)个点选一个点,然后连边。

但这里要考虑到边的顺序——因为数组有下标顺序,如果不考虑这个顺序的话,方案数就是 \(O((k(n-k))^m)\),但是这里面有很多重复的情况。考虑如何不计重。然后来写题解了

神奇的代码



标签:AtCoder,Beginner,int,auto,cin,long,327,tie,using
From: https://www.cnblogs.com/Lanly/p/17809838.html

相关文章

  • Atcoder Grand Contest 016
    给我贺完了?A-Shrinking给定一个串\(s\),每次可以进行如下操作:记串长为\(n\).构造长为\(n-1\)的串\(s'\),满足\(s'_i\)为\(s_i\)或\(s_{i+1}\),令\(s\leftarrows'\).问使\(s\)中所有字符相同的最小操作次数。\(|s|\le100\).按照题意模拟即可,时间复杂度......
  • AtCoder Beginner Contest 326 (ABC326)
    A.2UP3DOWN直接模拟即可。CodeB.326-likeNumbers枚举,每次拆除百、十、个位,再判断。CodeC.PeakDescription数字线上放置了\(N\)个礼物。第\(i\)个礼物放置在坐标\(A_i\)处。可以在数轴上选择长度为\(M\)的半开区间\([x,x+M)\),并获得其中包含的所有礼物。求:......
  • AtCoder Beginner Contest 224 H Security Camera 2
    洛谷传送门AtCoder传送门直接糊一手线性规划对偶板板。要求:\[\min\sumA_il_i+\sumB_ir_i\]\[\foralli,j,l_i+r_j\geC_{i,j}\]\[l_i,r_i\ge0\]\[l_i,r_i\in\mathbb{Z}\]可以证明\(l_i,r_i\)为整数的限制可以去掉,因为取到最优解时\(l_i,r_i\)一......
  • AtCoder Beginner Contest(abc) 314
    B-Roulette难度:⭐题目大意有一个猜数字的游戏,有n个人参加,每人都猜了若干个数;最后给出答案数字;在所有猜中数字的人中输出猜数数量最少的人的编号;(可能不止一个);解题思路数据不大,暴力即可;神秘代码#include<bits/stdc++.h>#defineintlonglong#def......
  • AtCoder Beginner Contest 326 F
    F-RobotRotation一句话不开LL,见祖宗感谢大佬,和洛谷上的题解上面已经将的很清楚了,但是如果你跟我一样一开始看不懂他们的代码,那么这篇可能为你解惑点击查看代码#include<bits/stdc++.h>usingnamespacestd;#defineLLlonglong#defineintLL//LL!map<LL,LL>ma;......
  • AtCoder Beginner Contest(abc) 312
    B-TaKCode难度:⭐题目大意题目定义一种矩阵X:该矩阵的是一个长度为9的由黑白色块组成正方形矩阵;该矩阵的左上角和右下角都是一个3*3的黑色矩阵(总共18个),这两个黑色矩阵外面(边缘不算)包围一圈白色色块(总共14个);现在一个n*m的黑白矩阵,问这个大矩阵中有多少......
  • AT_abc326_e Revenge of "The Salary of AtCoder Inc." 题解
    AT_abc326_eRevengeof"TheSalaryofAtCoderInc."题解一道简单的概率论+动态规划题目(然而我赛时没看这道题题意有一个长度为\(n\)的序列\(A\)、一个\(n\)面骰子,掷若干次骰子,如果这一次掷骰子的点数小于等于上一次的点数,则结束。定义这若干次掷骰子的总的结果为,每次......
  • AtCoder Beginner Contest(abc) 311
    B-VacationTogether难度:⭐题目大意给定n个人的工作计划,'o'表示这天休息,'x'表示工作;请找出一段最长的所有人都休息的连续休息的天数;解题思路数据不大,暴力即可;神秘代码#include<bits/stdc++.h>#defineintlonglong#defineIOSios::sync_with_stdio......
  • AtCoder Beginner Contest 321(ABC321)
    A.321-likeChecker直接模拟。CodeB.Cutoff直接暴力枚举\([0\sim100]\),每次把第\(n\)个数当作当前枚举的\(i\),然后看看条件是否满足。CodeC.321-likeSearcherDescription给你一个\(K\),求出\([1\simK]\)区间内有多少个321-likeNumber。321-likeNumber的......
  • Atcoder Beginner Contest 326 (ABC326)
    不知道为什么拖到现在,我是摆怪。A.2UP3DOWN模拟,略。B.326-likeNumbers模拟,略。C.Peak双指针板子。D.ABCPuzzle基础dfs。但是赛时不知道为什么觉得状态数不会很少,于是写了一个巨大复杂的状压。这里粗略算算有效状态数:仅考虑每行的限制,有\(\binom{3}{5}=10\)种选......