• AtCoder Beginner Contest 198[C-E]


    AtCoder Beginner Contest 198

    The competition link is here

    Question A and B is too easy, so i won't write the editorial.


    C - Compass Walking

    Problem Statement

    You are standing at the origin of a two-dimensional plane. For each step you can move to a point whose your distance from you current position is exactly (R) (the coordinate of the destination of a move do not have to be intergers), find the minimum number of steps you has to take before reaching ((X, Y)).

    Constraints

    • (1 le R le 10^5)

    • (0 le X, Y le 10^5)

    • ((X,Y) eq (0, 0))

    • All values in input are integers

    Solution

    好吧,还是写中文博客比较快。这题就是要考虑一个特殊情况。

    分两种情况考虑,显然是走两点之间的直线上,不妨设距离为(dist)

    • 恰好走完:(dist \% R == 0), 则直接除即可,(ans = dist/R)

    • 不能恰好走完:

      • (dist > R), 向上取整即可,考虑最后一步无法恰好达到则需要转为两步,(ans=lceil dist/R ceil)
      • (dist < R), 特判为(2),至少需要两次。

    Code

    using ll = long long;
    void solve(){
      ll r, x, y;
      std::cin >> r >> x >> y;
      ll ans = ceil(sqrt(x * x + y * y) / r);
      if (x * x + y * y < r * r) ans = 2;
      std::cout << ans << "
    ";
    }
    

    D - Send More Money

    Problem Statement

    给定三个字符串(S_1, S_2, S_3),要求(S_1 + S_2 = S_3)。要求给出(N_1, N_2, N_3), 满足:

    • (N_1 + N_2 = N_3)
    • 每个字母代表且仅代表一个数字,同理数字也只代表最多一个。
    • 不能有前导零

    Constraints

    • Each of (S_1, S_2, S_3) is a string of length between (1) and (10) (inclusive) consisting of lowercase English letters.

      Solution

    比赛的时候没写出来,显然多于(10)个字母就直接没有解。少于(10)个的直接用next_permutation暴力找,再特判前导零即可。

    Code

    void bad(){
        std::cout << "UNSOLVABLE
    ";
        exit(0); // 直接退出
    }
    
    void solve(){
        vt<string> s(3);
        rep (i, 0, 3) std::cin >> s[i];
    
        map<char, int> mp;
        for (auto v: s){
            for (auto c: v) ++ mp[c];
        }    
        if (mp.size() > 10) bad();
    
        int m = mp.size();
        string tar = "";
        vt<int> num(10); 
        iota(all(num), 0);
        for (auto e: mp) tar += e.first;
    
        auto get_val = [&](char ch){
            rep (i, 0, m){
                if (ch == tar[i]) return num[i];
            }
            return -1ll;
        };
    
        do {
            if (get_val(s[0].front()) == 0 or get_val(s[1].front()) == 0 or get_val(s[2].front()) == 0) continue;
            int x1(0), x2(0), x3(0);
            for (auto ch: s[0]){
                x1 *= 10;
                x1 += get_val(ch);
            }
            for (auto ch: s[1]){
                x2 *= 10;
                x2 += get_val(ch);
            }
            for (auto ch: s[2]){
                x3 *= 10;
                x3 += get_val(ch);
            }
            if (x1 + x2 == x3){
                std::cout << x1 << "
    ";
                std::cout << x2 << "
    ";
                std::cout << x3 << "
    ";
                return;
            }
        } while (next_permutation(all(num)));
        std::cout << "UNSOLVABLE
    ";
    }
    

    E - Unique Color

    Problem Statement

    每个点有自己的颜色,给一颗树,并定义好的点为:

    • 从点1到该点的最短路径中不存在重复颜色则为好的点。

    请找到所有好的点。

    Constraints

    • (2≤N≤10^5)
    • (1≤Ci≤10^5)
    • (1≤Ai,Bi≤N)
    • The given graph is a tree.
    • All values in input are integers.

    Solution

    这题WA了几发,没看清楚题目。

    由于这个是树结构,则一次从结点(1)dfs就可以找到最短路径。(假如是带权图等,我们可以用基于heapdijkstra并记录路径便可以保证时间复杂度。)需要注意的是,我们并不能简单的记录路径上某个颜色是否用过。我们应该记录颜色的数量,否则我们可能会误判,因为dfs访问之后需要进行回溯,所以假如用0-1变量的话直接清空会导致误判没有改颜色,实际上我们应该用++进行处理。

    Code

    const int maxn = 1e5 + 50;
    vt<int> E[maxn];
    int color[maxn], use[maxn];
    void solve(){
        mst(use, 0);
        int n; std::cin >> n;
        rep (i, 1, n + 1) std::cin >> color[i];
        rep (i, 0, n + 1) E[i].clear();
        rep (i, 0, n - 1){
            int u, v; std::cin >> u >> v;
            E[u].pb(v), E[v].pb(u);
        }
        
        vt<int> ans;
        function<void(int, int)> dfs = [&](int cur, int fa){
            if (!use[color[cur]]) ans.pb(cur);
            ++use[color[cur]]; // 增加访问
            
            for (auto go: E[cur]){
                if (go == fa) continue;
                dfs(go, cur);
                --use[color[go]]; // 访问结束
            }
        };
    
        dfs(1, 0);
        sort(all(ans));
        for (auto x: ans) std::cout << x << "
    ";
    }
    
  • 相关阅读:
    eslint 规则
    我的.eslintrc.js
    shell命令
    .sync 修饰符的理解
    【HNOI 2018】寻宝游戏
    【BZOJ 2820】YY的GCD
    【Luogu P2664】树上游戏
    【HAOI 2012】高速公路
    句摘
    【SCOI 2008】奖励关
  • 原文地址:https://www.cnblogs.com/Last--Whisper/p/14649806.html
Copyright © 2020-2023  润新知