zoukankan      html  css  js  c++  java
  • 2021牛客暑期多校训练营5 个人补题记录

    比赛链接:Here

    1001 - Away from College

    1002 - Boxes

    思路:只要使用一次hints,以后的每一步都可以知道剩下多少个黑球。所以最少花费是全部盒子开一遍或者先用一次hints后面再碰运气,注意到,每开一个盒子都有一定概率直接结束(后面全都是白球或全都是黑球)

    所以先排序,枚举前缀和至倒数第二个盒子,再乘以概率 (frac12^{n - i} imes2)

    最后答案为:(ans = min(sum[n],c + sumlimits_{i = 1}^{n - 1}(sum[i] * frac12^{n - i + 1})))


    试一下样例

    (n = 4,C = 0.123456\1 1 1 1)

    前缀和分别是 (1,2,3,4)

    (ans = min(4,0,123456 + 1∗1/8+2∗1/4+3∗1/2) = min(4,2.248456)=2.248456)

    代码
    const int N = 1e5 + 10;
    double a[N];
    int main() {
        // cin.tie(nullptr)->sync_with_stdio(false);
        int n; double c;
        cin >> n >> c;
        double sum = 0.0, ans = 0.0;
        for (int i = 1 ; i <= n; ++i) cin >> a[i], sum += a[i];
        sort(a + 1, a + 1 + n);
        double f = 1.0;
        for (int i = n; i > 0; i -= 1) {
            ans += (1.0 - f) * a[i];
            f /= 2.0;
        }
        cout << fixed << setprecision(6) << min(sum, c + ans);
    }
    

    1003 - Cheating and Stealing

    1004 - Double Strings

    超级眼熟,没想到就是 19年 CCPC秦皇岛 C 题的改版。

    引用一下官网题解

    好的方案的构成是“一段相同的前缀+一个不同字符(a比b小)+长度相同的任意后缀”。枚举不同的字符在两个序列中的位置。

    (dp[i][j]) 表示只考虑 A 中的前 i 个字符和 B 中的前 j 个字符时的相同的子序列的个数,转移可以 (O(1)),这样可以统计出相同的前缀个数,这部分是 (O(|s|*|t|)) 的。

    长度相同的任意后缀也可以用类似的 dp 计算,或者设 A 中此时剩余长度为 x, B 中剩余长度为 y,不失一般性地设 (x≤y) ,现在要求的就是 (ΣC(x,i)*C(y,i) = ΣC(x,x-i)*C(y,i) = C(x+y,x)),这部分也是 (O(|s|*|t|)) 的。

    using ll = long long;
    #define mod 1000000007
    ll la, lb, adf[5010], adg[5010], f[5010], g[5010];
    char a[5010], b[5010];
    
    int main() {
        cin >> a + 1 >> b + 1;
        la = strlen(a + 1);
        lb = strlen(b + 1);
        for (int i = 1; i <= la; i++) {
            for (int j = 1; j <= lb; j++) adf[j] = adg[j] = 0;
            for (int j = 1; j <= lb; j++) {
                if (a[i] == b[j]) adg[j] = g[j - 1] + 1;
                adf[j] = f[j - 1];
                if (a[i] < b[j]) adf[j] += g[j - 1] + 1;
            }
            for (int j = 1; j <= lb; j++) {
                adg[j] += adg[j - 1];
                adf[j] += adf[j - 1];
                g[j] += adg[j];
                f[j] += adf[j];
                adg[j] %= mod; adf[j] %= mod;
                g[j] %= mod; f[j] %= mod;
            }
        }
        cout << (f[lb] % mod + mod) % mod;
        return 0;
    }
    

    1005 - Eert Esiwtib

    1006 - Finding Points

    1007 - Greater Integer, Better LCM

    1008 - Holding Two (签到)

    题目描述

    在$n imes m$ 的 $01$ 矩阵中
    请问是否存在任意3个点 $(-1le x_1 - x_2 = x_2 - x_3 le 1,-1le y_1 - y_2 = y_2 - y_3 le 1)$
    如果存在则输出任何一种情况,否则输出 -1

    简单来说就是满足在横行,竖行,斜行中任意的连续的3个的元素不能都为0,或都为1;

    考虑了挺多情况发现下面这种写法对于任何 (n,m) 都成立

    [1100..\ 0011..\ 1100..\ .. ]

    【AC Code】

    int main() {
        cin.tie(nullptr)->sync_with_stdio(false);
        int n, m; cin >> n >> m;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j)
                cout << ((i & 1) ? ((j + 1) / 2 % 2) : !((j + 1) / 2 % 2));
            cout << "
    ";
        }
    }
    

    1009 - Interval Queries

    看不懂,没思路,fw二连

    1010 - Jewels

    题目描述

    把大海想象成一个三维坐标,我们的坐标为 $(0,0,0)$,现在有 $n$ 个宝石,但是每一秒宝石会以 $v_i$ 下沉,用 $d$ 来表示强度: 该时刻打捞的宝石与你之间的距离。请最小化总强度。


    开赛的时候看了下这个似乎是贪心排序就能写?自信交了一发,WA打脸。之后队友看出 (k) 才是签到,所以就比赛时没管这道题了

    正解的思路:所有的宝石肯定都在 (0) ~ (n-1)(n) 个时刻被挖掉,那么问题就变成一个最小权匹配了,一边是时刻,一边是宝石,边权就是在这个时刻挖这个宝石所消耗的体力值。

    稍微套一下板子就可以了

    代码
    ll n, ans;
    struct jew {ll z, v, id;} a[310];
    ll f(ll t, jew x) {t--; return t * t * x.v * x.v + 2 * t * x.v * x.z;} //边权
    void g(int x) {
        int t;
        for (int i = 1; i <= n; i++)  //找到当前宝石所匹配的时间
            if (a[i].id == x) {t = i; break;}
        for (int i = 1; i <= n; i++) { //枚举所有的边
            if (f(i, a[i]) + f(t, a[t]) > f(t, a[i]) + f(i, a[t])) { //找增广路
                swap(a[i], a[t]); //匹配宝石到时间更优的位置
                g(a[t].id); g(x); //暴力递归找增广路
            }
        }
    }
    int main() {
        cin >> n;
        for (int i = 1; i <= n; i++) {
            ll x, y, z, v;  cin >> x >> y >> z >> v;
            ans += x * x + y * y + z * z;
            a[i] = (jew) {z, v, i};
        }
        for (int i = 1; i <= n; i++) g(i);
        for (int i = 1; i <= n; i++) ans += f(i, a[i]); //累加答案
        cout << ans << "
    ";
        return 0;
    }
    

    1011 - King of Range

    题目描述

    长度 $n$ 的序列,定义区间大小为区间内最大值减去最小值的值,请问在 $m$ 次查询中有多少对区间严格大于 $k$


    (R_i)(l=i) 时,满足极差大于 (k) 的最小的 (r),如果不存在则记 (R_i = n+1)。那么显然有 (R_1 ≤ R_2 ≤ ... ≤ R_n)

    因为区间端点是单调的,明显的单调队列问题

    其中一个递增序列,队首维护最小值,一个递减序列,队首维护最大值,每次弹出两个队列中队首靠前的一个,直到极差 (≤ k)。那么就可以在均摊 (O(1)) 的时间内求 (R_i) 了。

    不过需要同时维护两个(一个求最大值,另一个求最小值)

    代码
    const int N = 1e5 + 10;
    int a[N], q1[N], q2[N], h1, t1, h2, t2;
    int main() {
        cin.tie(nullptr)->sync_with_stdio(false);
        int n, q;
        cin >> n >> q;
        for (int i = 1; i <= n; ++i) cin >> a[i];
        while (q--) {
            int k;
            cin >> k;
            h1 = h2 = t1 = t2 = 1;
            q1[1] = q2[1] = 1;
            int j = 1;
            ll ans = 0;
            for (int i = 1; i <= n; ++i) {
                if (q1[h1] < i) ++h1;
                if (q2[h2] < i) ++h2;
                while (j < i || a[q2[h2]] - a[q1[h1]] <= k) {
                    if (j == n)break;
                    ++j;
                    while (t1 >= h1 && a[q1[t1]] > a[j])--t1;
                    while (t2 >= h2 && a[q2[t2]] < a[j])--t2;
                    q1[++t1] = j;
                    q2[++t2] = j;
                }
                if (a[q2[h2]] - a[q1[h1]] <= k) break;
                ans += n - j + 1;
            }
            cout << ans << "
    ";
        }
    }
    

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    从句分析
    artDialog ( v 6.0.2 ) content 参数引入页面 html 内容
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 11 盛最多水的容器
    Java实现 LeetCode 11 盛最多水的容器
  • 原文地址:https://www.cnblogs.com/RioTian/p/15085186.html
Copyright © 2011-2022 走看看