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
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    json.parse 与 json.stringfy
    window.self ->window.top->window.parent
    Matrix探究细谈
    android TypedValue.applyDimension()的探究
    Android判断屏幕锁屏的步骤总结
    Intent和IntentFilter详解
    android中活动的启动模式
    android中的显式与隐式Intent
    android中的Pending.getActivity()参数详解
    android之传感器
  • 原文地址:https://www.cnblogs.com/RioTian/p/15085186.html
Copyright © 2011-2022 走看看