牛客小白月赛64(6/6)

小杜要迟到了!

模拟

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, k, a, b;
    cin >> n >> k >> a >> b;
    LL sum = (n - 1 + k - 1) * b;
    if (sum < (n - 1) * a) {
        cout << "1\n";
    } else if (sum > (n - 1) * a) {
        cout << "2\n";
    } else {
        cout << "0\n";
    }
    return 0;
}

小杜捕鱼

鱼的位置和四个角落的曼哈顿距离取最大

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m;
    cin >> n >> m;
    vector<string> a(n);
    int ans = 0;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (a[i][j] == '#') {
                ans = max({i + j, n - 1 - i + j, m - 1 - j + i, n - i + m - j - 2, ans});
            }
        }
    }
    cout << ans << '\n';
    return 0;
}

Karashi的生日蛋糕

考虑每一圈每块蛋糕至少要放多少块水果,因为是下取整,所以会有余数,要保持每圈之间每块蛋糕上水果差距不会太大,所以贪心的将余数水果优先分配给水果较少的蛋糕,如果还有剩余再分配给其他蛋糕

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, k;
    cin >> n >> k;
    vector<vector<int>> ans(k + 1, vector<int> (n + 1));
    int pos = 1;
    for (int i = 1; i <= n; i++) {
        int x = i / k, y = i % k;
        for (int j = 1; j <= k; j++) {
            ans[j][i] += x;
            if (y > 0) {
                y--;
                ans[pos][i]++;
                pos++;
                if (pos == k + 1) {
                    pos = 1;
                }
            }
        }
    }
    for (int i = 1; i <= k; i++) {
        for (int j = 1; j <= n; j++) {
            cout << ans[i][j] << " \n"[j == n];
        }
    }
    return 0;
}

Karashi的树 I

可知通过反转操作,可以把小的点权都放在子树小的地方,而点权越大放在子树越大的地方即可

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n + 1);
    vector<vector<int>> G(n + 1);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 2; i <= n; i++) {
        int x;
        cin >> x;
        G[i].push_back(x);
        G[x].push_back(i);
    }
    vector<int> sz(n + 1);
    function<void(int, int)> dfs = [&](int u, int fa) {
        sz[u] = 1;
        for (auto v : G[u]) {
            if (v != fa) {
                dfs(v, u);
                sz[u] += sz[v];
            }
        }
    };
    dfs(1, 0);
    sort(sz.begin() + 1, sz.end());
    sort(a.begin() + 1, a.end());
    LL ans = 0;
    for (int i = 1; i <= n; i++) {
        ans = ans + 1LL * a[i] * sz[i];
    }
    cout << ans << '\n';
    return 0;
}

Karashi的数组 I

将题目式子进行化简,发现满足条件当且仅当a[k]*a[k+len+1]=0,所以只需要提前处理出多少个符合条件的,然后每次单点修改讨论情况即可

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m, len;
    cin >> n >> m >> len;
    vector<int> a(n + 1);
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 1; i <= n - len - 1; i++) {
        if (1LL * a[i] * a[i + len + 1] == 0) {
            ans++;
        }
    }
    while (m--) {
        int pos, val;
        cin >> pos >> val;
        if (pos + len + 1 <= n and 1LL * a[pos] * a[pos + len + 1] == 0) {
            ans--;
        }
        if (pos - len - 1 >= 1 and 1LL * a[pos] * a[pos - len - 1] == 0) {
            ans--;
        }
        a[pos] = val;
        if (pos + len + 1 <= n and 1LL * a[pos] * a[pos + len + 1] == 0) {
            ans++;
        }
        if (pos - len - 1 >= 1 and 1LL * a[pos] * a[pos - len - 1] == 0) {
            ans++;
        }
        cout << ans << '\n';
    }
    return 0;
}

小杜跑酷

DP,一般思路就是从(1,1)一直转移到(1,n)(2,n)(3,n),但n的数值比较大,而如果很长时间没有经过机关,方案数是不变的,并且m较小,可以考虑直接看在机关处如何转移,发现只有中间那一行的机关在转移的时候和其他两行的机关有所不同,要特别判断在第几行,因此要提前按列数从小到大排序,每个机关至少要保留三列,所以要存储的最多是3*m列,然后就是一个基本的DP转移,当前点的方案数等于它前面所有下一步能走到它的方案数的和

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int mod = 998244353;
int mp[4][3 * 500020], nxt[500020];
LL dp[4][3 * 500020];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m;
    cin >> n >> m;
    vector<pair<int, int>> a(m);
    for (int i = 0; i < m; i++) {
        cin >> a[i].first >> a[i].second;
    }
    sort(a.begin(), a.end(), [&](pair<int, int> a, pair<int, int> b) {
        return a.second < b.second;
    });
    for (int i = 0; i < m; i++) {
        int dist = a[i].second - a[i - 1].second;
        nxt[i] = nxt[i - 1] + min(2, dist);
        mp[a[i].first][nxt[i]] = 1;
    }
    dp[1][1] = 1;
    for (int i = 1; i <= 3 * 500010; i++) {
        for (int j = 1; j < 4; j++) {
            if (!(j == 2 and mp[j][i - 1])) {
                dp[j][i] = (dp[j][i] + dp[j][i - 1]) % mod;
            }
            if (i - 2 >= 0 and mp[j][i - 2]) {
                dp[j][i] = (dp[j][i] + dp[j][i - 2]) % mod;
            }
            if (j >= 2 and mp[j - 1][i - 1]) {
                dp[j][i] = (dp[j][i] + dp[j - 1][i - 1]) % mod;
            }
            if (j <= 2 and mp[j + 1][i - 1]) {
                dp[j][i] = (dp[j][i] + dp[j + 1][i - 1]) % mod;
            }
        }
    }
    cout << dp[1][3 * 500010] << '\n';
    cout << dp[2][3 * 500010] << '\n';
    cout << dp[3][3 * 500010] << '\n';
    return 0;
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值