AtCoder Beginner Contest 424

链接:https://atcoder.jp/contests/abc424

A – Isosceles

算法:

    模拟。

思路:

    无。

关键代码:

void miyan()
{
    int a, b, c;
    cin >> a >> b >> c;

    if (a == b || b == c || c == a)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
}

B – Perfect

算法:

    模拟。

思路:

    无。

关键代码:

void miyan()
{
    int n, m, k;
    cin >> n >> m >> k;

    vector st(n + 1, vector<int>(m + 1, 0));
    while (k--)
    {
        int a, b;
        cin >> a >> b;
        st[a][b] = 1;

        if (accumulate(all(st[a]), 0) == m)
            cout << a << ' ';
    }

    cout << endl;
}

C – New Skill Acquired

算法:

    模拟,\(STL\)。

思路:

    无。

关键代码:

void miyan()
{
    int n;
    cin >> n;

    ll ans = 0;
    vector<int> st(n + 1, 0);
    map<int, vector<int>> m;
    vector<int> ok;
    ok.reserve(n);
    for (int i = 1; i <= n; ++i)
    {
        int x, y;
        cin >> x >> y;
        m[x].push_back(i);
        m[y].push_back(i);

        if (!x && !y)
        {
            st[i] = 1;
            ok.push_back(i);
            ++ans;
        }
    }

    for (int i = 0; i < ok.size(); ++i)
    {
        for (auto x : m[ok[i]])
        {
            if (!st[x])
            {
                ++ans;
                st[x] = 1;
                ok.push_back(x);
            }
        }
    }

    cout << ans << endl;
}

D – 2×2 Erasing 2

算法:

    暴搜。

思路:

    暴搜在每个 '#' 上转换成 '.' 的情况,暴搜出所有可能,更新最小答案即可。

关键代码:

void miyan()
{
    int n, m;
    cin >> n >> m;
    vector<string> g(n);
    for (int i = 0; i < n; ++i)
        cin >> g[i];

    ll ans = INT_MAX;
    auto dfs = [&](auto &&self, ll res, int x, int y) -> void
    {
        if (res >= ans)
            return;

        if (y == m)
            ++x, y = 0;

        if (x == n)
        {
            ans = res;
            return;
        }

        if (g[x][y] == '.')
            return self(self, res, x, y + 1);

        if (!x || !y || g[x - 1][y - 1] == '.' || g[x - 1][y] == '.' || g[x][y - 1] == '.')
            self(self, res, x, y + 1);

        g[x][y] = '.';
        self(self, res + 1, x, y + 1);
        g[x][y] = '#';
    };

    dfs(dfs, 0, 0, 0);

    cout << ans << endl;
}

E – Cut in Half

算法:

    堆。

思路:

    在大根堆中存储每个元素的值和出现次数,每次对相等的全部元素分割,最后再遍历堆,取第 \(x\) 大的数即可。

关键代码:

void miyan()
{
    ll n, k, x;
    cin >> n >> k >> x;
    map<double, int> m;
    for (int i = 0; i < n; ++i)
    {
        double x;
        scanf("%lf", &x);
        ++m[x];
    }

    priority_queue<pair<double, ll>> q;
    for (auto [x, y] : m)
        q.push({x, y});

    while (k)
    {
        auto [val, cnt] = q.top();
        q.pop();

        if (k >= cnt)
        {
            q.push({val / 2.0, cnt * 2ll});
            k -= cnt;
        }
        else
        {
            q.push({val, cnt - k});
            q.push({val / 2.0, k * 2ll});
            k = 0;
        }
    }

    while (q.size())
    {
        auto [val, cnt] = q.top();
        q.pop();

        if (cnt >= x)
        {
            printf("%.15lf\n", val);
            return;
        }

        x -= cnt;
    }
}

F – Adding Chords

算法:

    线段树。

思路:

    可以发现在圆上两条线段 \([a, b](a < b)\),\([c, d](c < d)\) 相交需要满足 \(a < c < b < d\) 或者 \(c < a < d < b\)。

    那么对于当前线段只需寻找起点在 \([a – 1, b – 1]\) 之间并且终点在 \(b\) 后面的点,如果存在就说明相交。

    另一个条件同理,只需寻找终点在 \([a – 1, b – 1]\) 之间并且起点在 \(a\) 前面的点,如果存在就说明相交。

    \(n\) 的级别为 \(1e6\)。使用线段树维护,要判断当前线段与之前线段会不会相交,只需判断以上两个条件都不满足即可。

    既在起点区间 \([a – 1, b – 1]\) 之间找最大的终点,其值小于等于 \(b\),并且在终点区间 \([a – 1, b – 1]\) 之间找最小的起点,其值大于等于 \(a\)。

关键代码:

template <typename T>
struct SegmentTreeMin
{
    struct Node
    {
        int l, r;
        T minn;
    };

    // 线段树大小
    int N;
    vector<Node> tr;
    vector<T> v;

    SegmentTreeMin(int _N, const vector<T> &_v)
    {
        N = _N;
        v.resize(N + 10);
        for (int i = 1; i <= N; ++i)
            v[i] = _v[i];
        tr.resize(4 * N);
        build(1, 1, N);
    }

// 左右子区间
#define LC (u << 1)
#define RC ((u << 1) | 1)

    inline void pushup(int u)
    {
        tr[u].minn = min(tr[LC].minn, tr[RC].minn);
    }

    inline void build(int u, int l, int r)
    {
        if (l == r)
        {
            tr[u] = {l, r, v[l]};
            return;
        }

        tr[u] = {l, r};
        int mid = l + r >> 1;
        build(LC, l, mid);
        build(RC, mid + 1, r);
        pushup(u);
    }

    inline T query(int u, int l, int r)
    {
        if (tr[u].l >= l && tr[u].r <= r)
            return tr[u].minn;

        int mid = tr[u].l + tr[u].r >> 1;
        T ans = std::numeric_limits<T>::max(); // 当前类型能表示的最大值
        if (l <= mid)
            ans = min(ans, query(LC, l, r));
        if (r > mid)
            ans = min(ans, query(RC, l, r));
        return ans;
    }

    inline void update(int u, int x, T val)
    {
        if (tr[u].l == x && tr[u].r == x)
        {
            tr[u].minn = val;
            return;
        }

        int mid = tr[u].l + tr[u].r >> 1;
        if (x <= mid)
            update(LC, x, val);
        else
            update(RC, x, val);
        pushup(u);
    }

    inline T query(int l, int r) { return query(1, l, r); }

    inline void update(int x, T val) { update(1, x, val); }
};

template <typename T>
struct SegmentTreeMax
{
    struct Node
    {
        int l, r;
        T maxx;
    };

    // 线段树大小
    int N;
    vector<Node> tr;
    vector<T> v;

    SegmentTreeMax(int _N, const vector<T> &_v)
    {
        N = _N;
        v.resize(N + 10);
        for (int i = 1; i <= N; ++i)
            v[i] = _v[i];
        tr.resize(4 * N);
        build(1, 1, N);
    }

// 左右子区间
#define LC (u << 1)
#define RC ((u << 1) | 1)

    inline void pushup(int u)
    {
        tr[u].maxx = max(tr[LC].maxx, tr[RC].maxx);
    }

    inline void build(int u, int l, int r)
    {
        if (l == r)
        {
            tr[u] = {l, r, v[l]};
            return;
        }

        tr[u] = {l, r};
        int mid = l + r >> 1;
        build(LC, l, mid);
        build(RC, mid + 1, r);
        pushup(u);
    }

    inline T query(int u, int l, int r)
    {
        if (tr[u].l >= l && tr[u].r <= r)
            return tr[u].maxx;

        int mid = tr[u].l + tr[u].r >> 1;
        T ans = std::numeric_limits<T>::min(); // 当前类型能表示的最大值
        if (l <= mid)
            ans = max(ans, query(LC, l, r));
        if (r > mid)
            ans = max(ans, query(RC, l, r));
        return ans;
    }

    inline void update(int u, int x, T val)
    {
        if (tr[u].l == x && tr[u].r == x)
        {
            tr[u].maxx = val;
            return;
        }

        int mid = tr[u].l + tr[u].r >> 1;
        if (x <= mid)
            update(LC, x, val);
        else
            update(RC, x, val);
        pushup(u);
    }

    inline T query(int l, int r) { return query(1, l, r); }

    inline void update(int x, T val) { update(1, x, val); }
};

void miyan()
{
    int n, q;
    cin >> n >> q;

    SegmentTreeMin<int> segmin(n, vector<int>(n + 1, INT_MAX));
    SegmentTreeMax<int> segmax(n, vector<int>(n + 1, INT_MIN));

    while (q--)
    {
        int a, b;
        cin >> a >> b;

        int val1 = segmin.query(a + 1, b - 1);
        int val2 = segmax.query(a + 1, b - 1);

        if (val1 >= a && val2 <= b)
        {
            cout << "Yes" << endl;
            segmin.update(b, a);
            segmax.update(a, b);
        }
        else
            cout << "No" << endl;
    }
}

G – Set list

    还没补。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇