Atcoder Beginner Contest 304 A~E题解

本文包含五道编程题目,涉及到数组、字符串、图论等算法知识,如按年龄顺序输出名字、处理数字抹去部分位数、病毒传播模拟、蛋糕切割问题以及无向图的连通性判断。每道题目都提供了相应的解决方案和代码实现。
摘要由CSDN通过智能技术生成

A - First Player

题目链接
题目:从1~N编号的人顺时针围在桌子,每个人都有不同的名字和年龄,从最年轻的人开始输出名字

  • 简单模拟一下
# include <bits/stdc++.h>
# define int long long
# define endl '\n'
# define x first
# define y second
# define INF 0x3f3f3f3f
# define pii pair<string, int>
# define uf(i, j, k) for (int i = j; i <= k; i ++)
# define df(i, j, k) for (int i = j; i >= k; i --)
# define mset(x, v) memset(x, v, sizeof x)

using namespace std;

void solve()
{
    int n;
    cin >> n;
    vector<pii> p(n);
    int pos = 0, cur = INF;
    uf (i, 0, n - 1) 
    {
        string s;
        int age;
        cin >> s >> age;
        p[i] = {s, age};
        if (age < cur) {cur = age, pos = i;}
    }
    uf (i, pos, n - 1) cout << p[i].first << endl;
    uf (i, 0, pos - 1) cout << p[i].x << endl;

}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t --) solve();
    return 0;
}

B - Subscribers

题目链接
题目:根据不同范围抹去不同数位后面的数字

  • 根据题目判断
# include <bits/stdc++.h>
# define int long long
# define endl '\n'
# define x first
# define y second
# define INF 0x3f3f3f3f
# define pii pair<int, int>
# define uf(i, j, k) for (int i = j; i <= k; i ++)
# define df(i, j, k) for (int i = j; i >= k; i --)
# define mset(x, v) memset(x, v, sizeof x)

using namespace std;

void solve()
{
    int n, ans;
    cin >> n;
    if (n < 1e3) ans = n;
    else if (n < 1e4) ans = (n / 10) * 10;
    else if (n < 1e5) ans = (n / 100) * 100;
    else if (n < 1e6) ans = (n / 1000) * 1000;
    else if (n < 1e7) ans = (n / 10000) * 10000;
    else if (n < 1e8) ans = (n / 100000) * 100000;
    else ans = (n / 1000000) * 1000000; 
    cout << ans << endl;

}

signed main()
{
    freopen("C:\\Users\\swk\\Desktop\\Problems\\.in", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t --) solve();
    return 0;
}

C - Virus

题目链接
题目:一种病毒在人与人之间的距离小于等于 d 时会传染,编号1的人感染了了病毒,给出 n 个人的位置,判断足够时间后哪些人会被感染?

  • 建立图,只有人与人之间的距离小于等于 d 才建立边,最后进行BFS即可
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define x first
#define y second
#define INF 0x3f3f3f3f
#define pii pair<int, int>
#define uf(i, j, k) for (int i = j; i <= k; i++)
#define df(i, j, k) for (int i = j; i >= k; i--)
#define mset(x, v) memset(x, v, sizeof x)

using namespace std;

void solve()
{
    int n, d;
    cin >> n >> d;
    auto get = [](int x, int y, int a, int b)
    {
        return sqrt((x - a) * (x - a) + (y - b) * (y - b));
    };
    vector<pii> p(n);
    vector<vector<int>> e(n + 1);
    uf(i, 0, n - 1) cin >> p[i].x >> p[i].y;
    uf(i, 0, n - 1) uf(j, 0, n - 1)
    {
        if (i != j)
        {
            double w = get(p[i].x, p[i].y, p[j].x, p[j].y);
            if (w <= d)
                e[i].push_back(j), e[j].push_back(i);
        }
    }
    bool st[n]{};
    queue<int> q;
    q.push(0);
    while (q.size())
    {
        auto u = q.front();
        q.pop();
        if (st[u]) continue;
        st[u] = true;
        for (auto v : e[u])
        {
            q.push(v);
        }
    }
    uf(i, 0, n - 1)
    {
        if (st[i])
            cout << "Yes" << endl;
        else
            cout << "No" << endl;
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
    return 0;
}

D - A Piece of Cake

题目链接
题目:给一块矩形蛋糕,上面有 n 颗草莓,给出它们的坐标,现在给这块蛋糕横着在指定位置切 a 刀,竖着在指定位置切 b 刀,问分成若干块,在这些块中某一块最少草莓的数量和最多草莓的数量

  • 我们只需要统计出每一块的草莓数量即可,暴力不可行,可以通过二分
  • 对于每个草莓的位置进行二分,找出最近横着切的位置和最近竖着切的位置,用哈希统计该位置的草莓数量
  • 最后排序,输出最少和最多的草莓数量(注意有些块上面会没有草莓,即最少为0,需要判断一下哈希表维护的位置个数)
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define x first
#define y second
#define INF 0x3f3f3f3f
#define pii pair<int, int>
#define uf(i, j, k) for (int i = j; i <= k; i++)
#define df(i, j, k) for (int i = j; i >= k; i--)
#define mset(x, v) memset(x, v, sizeof x)
/*
    @see
*/
using namespace std;
const int N = 2e5 + 5;
vector<pii> c(N);
vector<int> a(N), b(N);
void solve()
{
    int w, h, n;
    cin >> w >> h >> n;
    uf(i, 1, n) cin >> c[i].x >> c[i].y;
    int al, bl;
    cin >> al;
    uf(i, 1, al) cin >> a[i];
    cin >> bl;
    uf(i, 1, bl) cin >> b[i];
    unordered_map<int, int> mp;
    auto get = [&](pii t)
    {
        int l = 0, r = al;
        while (l < r)
        {
            int mid = l + r + 1 >> 1;
            if (a[mid] < t.x) l = mid;
            else r = mid - 1;
        }
        int x = l;
        l = 0, r = bl;
        while (l < r)
        {
            int mid = l + r + 1 >> 1;
            if (b[mid] <= t.y) l = mid;
            else r = mid - 1;
        }
        return x * N + l;
    };
    uf(i, 1, n)
    {
        int t = get(c[i]);
        mp[t] ++;
    }
    vector<pii> ans(mp.begin(), mp.end());
    sort(ans.begin(), ans.end(), [&](pii a, pii b) {return a.y < b.y;});
    int cnt = (al + 1) * (bl + 1);
    if (ans.size() < cnt) cout << 0 << " " << ans.back().y;
    else cout << ans[0].y << " " << ans.back().y << endl;
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
    return 0;
}

E - Good Graph

题目链接
题目:给一个 n 结点 m 边的无向图, 如果一张图对于 k 对结点没有相连的路径,那么认为这样图为 Good;对于 Q 个独立的问题,每个问题给某一对结点添加边,判断添加路径后的图仍然是 Good

  • 用并查集维护每一个连通分量,检查是否满足k对结点没有相连,用set维护该k对结点对应的k对连通分量
  • 对于每一个问题,检查所在连通分量是否存在于set中,如果存在那么添加边后,k对结点中肯定有结点相连,那么该图不是 Good,否则添加边后k对结点仍不相连,该图为 Good
# include <bits/stdc++.h>
# define int long long
# define endl '\n'
# define x first
# define y second
# define INF 0x3f3f3f3f
# define pii pair<int, int>
# define uf(i, j, k) for (int i = j; i <= k; i ++)
# define df(i, j, k) for (int i = j; i >= k; i --)
# define mset(x, v) memset(x, v, sizeof x)
/*
    @see 
*/
using namespace std;
const int N = 2e5 + 5;
int p[N];
int n, m;
int find(int x)
{
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}

void merge(int x, int y) 
{
    int dx = find(x), dy = find(y);
    if (dx != dy) p[dx] = dy;
}

void solve()
{
    cin >> n >> m;
    iota(p, p + N + 1, 0);
    while (m --) 
    {
        int u, v;
        cin >> u >> v;
        merge(u, v);
    }
    int k, q;
    cin >> k;
    bool ok = true;
    set<pii> st;
    uf (i, 1, n) find(i);
    while(k --)
    {
        int u, v;
        cin >> u >> v;
        int dx = find(u), dy = find(v);
        ok &= dx != dy;
        if (ok) 
        {
            if (dx > dy) swap(dx, dy);
            st.insert({dx, dy});   
        }
    }
    cin >> q;
    while (q --)
    {
        int u, v;
        cin >> u >> v;
        int dx = find(u), dy = find(v);
        if (dx > dy) swap(dx, dy);
        if (st.count({dx, dy}) || !ok) cout << "No" << endl;
        else cout << "Yes" << endl; 
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t --) solve();
    return 0;
}

想过离开 当阳光败给阴霾
没想到你会拼命为我拨开
曾想过离开 却又坚持到现在
熬过了 那些旁白 那些姿态
那些伤害
不想离开 当你的笑容绽开
这世界突然填满 色彩

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值