AtCoder Beginner Contest 373

A - September

思路

判断字符串长度是否等于当前位次即可

AC代码

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    using namespace std;
    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef priority_queue<int> PQ;

    const int N = 2e5+10, MAX = 1e9, INF = -1e9;

    string s;
    int ans=0;

    signed main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        for(int i=1;i<=12;i++){
        cin>>s;
        if(s.size()==i)ans++;
        }
        cout<<ans<<endl;

        return 0;
    }

B - 1D Keyboard

思路

打表,用map储存每个字母的位置,然后从A到Z查表加上距离即可

AC代码

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    using namespace std;
    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef priority_queue<int> PQ;

    const int N = 2e5+10, MAX = 1e9, INF = -1e9;

    map<char,int> mp;
    int ans=0;

    signed main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        char c;
        for(int i=1;i<=26;i++){
            cin>>c;
            mp[c]=i;
        }
        char x='A';
        for(int i=0;i<25;i++){
            ans+=(abs(mp[x]-mp[x+1]));
            x++;
        }
        cout<<ans<<endl;

        return 0;
    }

C - Max Ai+Bj

思路

不用排序,甚至不需要数组,在输入中找到最大输出即可,时间复杂度为\(O(n)\),空间复杂度为\(O(1)\),(个人打Atcoder以来最水的C,只有A题难度)

AC代码

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    using namespace std;
    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef priority_queue<int> PQ;

    const int N = 2e5+10, MAX = 1e9, INF = -1e9;

    int n;
    int a = INF -1;
    int b = INF -1;
    int e;

    signed main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>e;
            a=max(e,a);
        }
        for(int i=1;i<=n;i++){
            cin>>e;
            b=max(e,b);
        }
        cout<<a+b<<endl;
        
        return 0;
    }

D - Hidden Weights

思路

仿照求岛屿数量的问题,从1~n进行DFS,将每个独立的连通块根节点赋值为0,从根节点向下遍历按照公式赋值即可,但是这里有一种特殊情况:

某个叶节点同时被多根节点连接

考虑以下输入:

    3 2
    1 3 1
    2 3 -1

以上述数据所构成的图如下所示:

根据遍历每个根节点赋值为0并向下探索的思路,我们不难发现:由1节点遍历出3节点应当赋值为1,但是由2节点遍历出3节点的值却是-1,这显然矛盾,所以针对以上特殊情况我们需要改变思路,我的解决方案是反转边的方向,即将这中情况中的多根变为一根,指定一个主根节点,从原始叶节点开始,将其余根节点路径反转(如下图),这样就将这种特殊情况转化成了一般情况:

具体方案是再储存一个反转所有边的有向图,对于每次DFS,先按照原图正向遍历,再按照反图逆向遍历一次,问题就解决了,每个点只遍历一次,时间复杂度为\(O(n)\);

AC代码

    #include<bits/stdc++.h>
    #define endl '\n'
    #define int int long long
    #define pb push_back
    #define bs bitset
    using namespace std;
    typedef pair<char,int> PCI;
    typedef pair<int,int> PII;
    typedef priority_queue<int> PQ;

    const int N = 2e5+10, MAX = 1e9, INF = -1e9;

    int n,m;
    int u,v,w;
    map<int,vector<int>> mp;
    map<int,vector<int>> rmp;
    map<PII,int> W;
    bool st[N];
    int ans[N];

    void dfs(int x,int e){
        ans[x]=e;
        for(auto i:mp[x]){
            if(!st[i]){
                ans[i]=e+W[{x,i}];
                st[i]=true;
                dfs(i,ans[i]);
            }
        }
        for(auto i:rmp[x]){
            if(!st[i]){
                ans[i]=e+W[{x,i}];
                st[i]=true;
                dfs(i,ans[i]);
            }
        }
    }

    signed main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>n>>m;

        for(int i=1;i<=m;i++){
            cin>>u>>v>>w;
            mp[u].pb(v);
            rmp[v].pb(u);
            W[{u,v}]=w;
            W[{v,u}]=-w;
        }

        for(int i=1;i<=n;i++){
            if(!st[i]){
                st[i]=true;
                dfs(i,0);
            }
        }
        for(int i=1;i<=n;i++)cout<<ans[i]<<" ";

        return 0;
    }

t.b.c.

posted @ 2024-09-29 18:42  Oaths  阅读(57)  评论(0)    收藏  举报