ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AtCoder Beginner Contest 257 A - F

2022-07-02 15:33:34  阅读:143  来源: 互联网

标签:AtCoder Beginner int cin num maxn include 257 dis


传送门

vp 了一场之前的 ABC,不知道是水平下降还是真的难,就很多要想很久,寄了

A - A to Z String 2

向下取整考虑一下是在哪个组就好

#include <iostream>
using namespace std;

int main()
{
    int n, x;
    cin >> n >> x;
    x--;
    x /= n;
    cout << (char)('A' + x) << endl;
    return 0;
}

B - 1D Pawn

模拟

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e4 + 10;
int num[maxn], vis[maxn];

int main()
{
    int n, k, q;
    cin >> n >> k >> q;
    for(int i=1; i<=k; i++)
    {
        cin >> num[i];
        vis[num[i]] = i;
    }
    while(q--)
    {
        int x;
        cin >> x;
        vis[num[x]] = 0;
        if(num[x] < n && vis[num[x] + 1] == 0)
            num[x]++;
        vis[num[x]] = 1;
    }
    // sort(num + 1, num + k + 1);
    for(int i=1; i<=k; i++)
    {
        if(i != 1) cout << " ";
        cout << num[i];
    }
    cout << endl;
    return 0;
}

C - Robot Takahashi

考虑从小到大枚举所有可能的答案,因为从小到大,所以总共为找所有 \(f(x)\) 的代价也就是 \(O(n)\),每次 x 增加的时候,就从上一次的答案继续往下查找

我一开始以为相同重量的成年人和小孩没办法分辨,因此取了相邻重量的两个人的中间值作为枚举的答案,但是后来发现有点蠢了,直接枚举所有人的重量就可以了

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#define pii pair<double, int>

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    string s;
    cin >> n >> s;
    vector<pii>a(n);
    vector<double>b;
    int ch = 0, ad = 0;
    for(int i=0; i<n; i++)
    {
        int x;
        cin >> x;
        a[i] = {x, s[i] - '0'};
        if(s[i] == '1') ad++;
    }
    sort(a.begin(), a.end());
    b.push_back(-1);
    for(int i=1; i<n; i++)
        b.push_back((a[i].first + a[i].first) / 2);
    b.push_back(1e9 + 10);
    
    int ans = ad, tp = 0;
    for(int i=0; i<b.size(); i++)
    {
        while(tp < n && a[tp].first < b[i])
        {
            if(a[tp].second == 1) ad--;
            else ad++;
            tp++;
        }
        ans = ad > ans ? ad : ans;
    }
    cout << ans << endl;
    return 0;
}

D - Jumping Takahashi 2

dijkstra 或 Floyd 或 二分

dijkstra 枚举从每个点出发到所有点的最大代价的最小值

同理,Floyd 跑完之后再找这个最小值

二分答案,通过 bfs 判断是否有个点能跑遍历所有的点

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
typedef long long ll;
#define pii pair<double, int>
const int maxn = 210;
const double eps = 1e-8;
ll gra[maxn][maxn];
int vis[maxn];

struct node
{
    ll x, y, val;
    node(){}
    node(ll _x, ll _y, ll _v){x = _x; y = _y; val = _v;}
    bool operator < (const node& a) const
    {
        return a.val < val;
    }
}num[maxn];

ll dis(node& a, node& b)
{
    return abs(a.x - b.x) + abs(a.y - b.y);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    for(int i=1; i<=n; i++)
        cin >> num[i].x >> num[i].y >> num[i].val;

    for(int i=1; i<=n; i++)
    {
        for(int j=i+1; j<=n; j++)
        {
            ll s = dis(num[i], num[j]);
            gra[i][j] = (s + num[i].val - 1) / num[i].val;
            gra[j][i] = (s + num[j].val - 1) / num[j].val;
        }
    }
    ll ans = 1e17 + 10;
    for(int i=1; i<=n; i++)
    {
        for(int j=j=1; j<=n; j++) vis[j] = 0;
        priority_queue<node>q;
        q.push(node(i, i, 0));
        ll temp = 0;
        int cnt = n;
        while(q.size() && cnt)
        {
            node now = q.top();
            q.pop();
            if(vis[now.y]) continue;
            cnt--;
            vis[now.y] = 1;
            temp = max(temp, now.val);
            for(int j=1; j<=n; j++)
                if(vis[j] == 0)
                    q.push(node(now.y, j, gra[now.y][j]));
        }
        ans = min(ans, temp);
    }
    cout << ans << endl;
    return 0;
}

E - Addition and Multiplication 2

首先要选个代价最小的,且价值最高,保证数字足够长

然后剩下的前就考虑如何从高位给数字“升级”,也就是枚举能够到的价值最高的数字

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
pii num[20];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    for(int i=0; i<9; i++)
    {
        int x;
        cin >> x;
        num[i] = {x, -(i + 1)};
    }
    sort(num, num + 9);
    for(int i=0; i<9; i++) num[i].second = -num[i].second;
    int cnt = n / num[0].first;
    int nn = n % num[0].first;
    if(cnt == 0) cout << 0;
    while(cnt && nn)
    {
        int way = num[0].second, ans = num[0].first + nn, x = 0;
        for(int i=1; i<9; i++)
        {
            if(num[i].first <= ans && num[i].second > way)
            {
                way = num[i].second;
                x = num[i].first;
            }
        }
        if(way == num[0].second) break;
        cout << way;
        nn = nn - x + num[0].first;
        cnt--;
    }
    while(cnt--) cout << num[0].second;
    cout << endl;
    
    return 0;
}

F - Teleporter Setting

bfs

先构建一个 0 号虚拟点,最后再遍历这个点是其他的点

答案有两种来源:

  1. 本身从 1 直接到达 n(可经过 0 号虚拟点)

  2. 经过 0 号虚拟点和当前假设的点 i 之间的代价为 0 的特殊边

对于第一种情况,只用计算最短路即可

对于第二种情况,则为 min(dis[1][0] + dis[i][n], dis[1][i] + dis[0][n])

综上,计算出 1 和 n 到其他所有点的最短路即可,然后枚举假设 0 号虚拟点为 i 号点,然后找最小的情况

我原本的写法比较笨,现在改用了上述这种写法

#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
#include <array>
#include <algorithm>
using namespace std;
const int maxn = 3e5 + 10;
const int inf = 1e8 + 10;
int n, m;
vector<int>gra[maxn];

vector<int> bfs(int s)
{
    queue<array<int, 2> >q;
    vector<int> dis(n + 1, inf);
    q.push({s, 0});
    while(q.size())
    {
        auto [x, d] = q.front();
        q.pop();
        if(dis[x] != inf) continue;
        dis[x] = d;
        for(auto i : gra[x])
            if(dis[i] == inf) q.push({i, d + 1});
    }
    return dis;
}

int main()
{
    cin >> n >> m;
    for(int i=0; i<m; i++)
    {
        int x, y;
        cin >> x >> y;
        gra[x].push_back(y);
        gra[y].push_back(x);
    }
    auto dis1 = bfs(1);
    auto disn = bfs(n);
    for(int i=1; i<=n; i++)
    {
        int ans = min({dis1[n], dis1[0] + disn[i], dis1[i] + disn[0]});
        if(ans == inf) ans = -1;
        if(i != 1) cout << " ";
        cout << ans;
    }
    cout << endl;
    return 0;
}

标签:AtCoder,Beginner,int,cin,num,maxn,include,257,dis
来源: https://www.cnblogs.com/dgsvygd/p/16437688.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有