• Codeforces Round #704 (Div. 2) A~C题解


    写在前边

    链接:Codeforces Round #704 (Div. 2)
    D就不补了,大fst场。

    A. Three swimmers

    链接:A题链接

    题目大意:

    给定三个游泳者的到达岸边的周期,(a,b,c),而你到达岸边的时间为(p),现在问你到达岸边后最少需要多少时间能遇到一名游泳者。

    思路

    老套路题了,公式:

    [res = min(lceil cfrac{p}{a} ceil * a, lceil cfrac{p}{b} ceil * b, lceil cfrac{p}{c} ceil * c) - p ]

    注意,写代码的时候((p + a - 1) / a * a)(a * (p + a - 1) / a)获得的结果也不一样,前一种正确。

    代码:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    #include <unordered_map>
    
    using namespace std;
    
    #define Inf 0x3f3f3f3f
    #define PII pair<int, int>
    #define P2LL pair<long long, long long>
    #define endl '
    '
    
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef vector<long long> VLL;
    typedef vector<int> VI;
    
    void solve() {
        LL p, a, b, c;
        cin >> p >> a >> b >> c;
        LL a1, b1, c1;
        a = (p + a - 1) / a * a;
        b = (p + b - 1) / b * b;
        c = (p + c - 1) / c * c;
    
        cout << min(a, min(b, c)) - p << endl;
    }
    
    int main()
    {
        //ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
        int t;
        cin >> t;
        while (t--) {
            solve();
        }
    
        return 0;
    } 
    

    B. Card Deck

    链接:B题链接

    题目大意:

    一副扑克盘,从上往下拿,截止点作为新牌的起点,会形成一种新的顺序,使得这种顺序权值最大,计算权值公式:

    [sumlimits_{i = 1}^n n^{n - i} * p_i ]

    思路

    把公式展开后就得出让新的牌须变成字典序最大即可,那么我们就每一次以剩余的最大数作为截止点拿牌,形成新的顺序,一开始就想到这种方法了,但是复杂度想成了(O(n^2))没敢做,于是看题解后,做的也是这种方法,于是想了一下复杂度并不是(O(n^2)),最坏是是(O(n + n))

    代码:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    #include <map>
    #include <cstring>
    #include <set>
    
    //#pragma GCC optimize(2)
    //#pragma GCC optimize(3,"Ofast","inline")
    
    using namespace std;
    
    #define Inf 0x3f3f3f3f
    #define PII pair<int, int>
    #define P2LL pair<long long, long long>
    #define endl '
    '
    
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef vector<long long> VLL;
    typedef vector<int> VI;
    
    const int Mod = 10000007;
    
    LL gcd(LL a, LL b) {
        return b ? gcd(b, a % b) : a;
    }
    
    const int N = 1e5 + 10;
    int a[N];
    
    void solve() {
        int n;
        scanf("%d", &n);
        
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        
        set<int> st;
        vector<int> rem;
        for (int i = 1; i <= n; i++) st.insert(i);
    
        int maxn = n;
        for (int i = n; i >= 1; i--) {
            rem.push_back(a[i]);
            st.erase(a[i]);
            if (a[i] == maxn) {
                reverse(rem.begin(), rem.end());
                for (auto &it : rem) cout << it << " ";
                rem.clear();
                if (st.size()) maxn = *(--st.end());
            }
        }
        cout << endl;
    }
    
    int main()
    {
        //ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
        int t;
        scanf("%d", &t); 
        while (t--) {
            solve();
        }
        return 0;
    }
    

    C. Maximum width

    链接:C题链接

    题目大意:

    给定一个长度分别为(n,m)的字符串(s,t),同时可以得到一个序列(p)(1 leq p_1 leq p_2 leq p_3 leq ... leq n),使得(s_{p_i} = t_i)对于所有的(s[1, m]),让我们构造以(p)得到一个(maxlimits_{1 leq i leq m} (p_{i + 1} - p_i))

    思路

    每次做这种题都会让坐标烦,这道题仔细抠一下题意就是在(s)中找到一个(t),并使得(t)(s)中相邻两个字母的坐标差最大,那么可以分别从前边可后边维护两个数组(f,g)(f_i)表示(t_i)在s中最左侧位置下标,(g_i)就表示(t_i)(s)中最右侧位置的下边,那么答案就是(maxlimits_{1 leq i leq {m - 1}} (g_{i + 1} - f_i))

    代码:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    #include <unordered_map>
    
    using namespace std;
    
    #define Inf 0x3f3f3f3f
    #define PII pair<int, int>
    #define P2LL pair<long long, long long>
    #define endl '
    '
    
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef vector<long long> VLL;
    typedef vector<int> VI;
    
    const int N = 2e5 + 10;
    char s[N], t[N];
    int f[N], g[N];
    
    void solve() {
        int n, m;
        scanf("%d%d", &n, &m);
        scanf("%s", s + 1);
        scanf("%s", t + 1);
    
        int cnt = 1;
        for (int i = 1; i <= m; i++) {
            while (s[cnt] != t[i]) cnt++;
            f[i] = cnt;
            cnt++;
        }
    
        cnt = n;
        for (int i = m; i >= 1; i--) {
            while (s[cnt] != t[i]) cnt--;
            g[i] = cnt;
            cnt--;
        }
    
        int res = 0;
        for (int i = 1; i <= m - 1; i++) res = max(res, g[i + 1] - f[i]);
        printf("%d
    ", res);
    }
    
    int main()
    {
        solve();
        return 0;
    } 
    
  • 相关阅读:
    iOS酷炫动画效果合集
    重载hash与isEqual:方法
    NSObject的hash方法
    带辉光效果的跑马灯
    线性重复动画
    TextKit简单示例
    计算一行文本的高度
    点击cell动态修改高度动画
    FastDFS图片服务器(分布式文件系统)学习。
    Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'jdbc.username' in string value "${jdbc.username}"
  • 原文地址:https://www.cnblogs.com/ZhengLijie/p/14470767.html
Copyright © 2020-2023  润新知