AcWing 第 60 场周赛 (RANK51)

简介: AcWing 第 60 场周赛 (RANK51)

@[TOC]

比赛链接: 第 60 场周赛

二十分钟下班,有进步。

在这里插入图片描述

B.AcWing 4495. 数组操作

题目

给定一个长度为 n 的正整数数组 a1,a2,…,an。

请你对该数组进行 k 次操作,每次操作具体如下:

  • 如果数组中存在非零元素,则找到其中的最小非零元素 x,将其输出,并让数组中的所有非零元素都减去 x。
  • 如果数组中不存在非零元素,则输出 0 即可。

思路: 模拟

因为每次操作都是先找到数组中的最小元素,并且让数组中每个元素都减去x,那么可以先将数组从小到大排序,此时数组呈非单调递减,全部都减去一个数后,也不影响数组的顺序,还是非单调递减。

那么我们就可以枚举每个元素,从前到后依次操作,最多进行k次。如果当前元素已经等于0的话那么就不能在操作了,找下一个大于0的数,如果直到最后还找不到k个的话,那么就都输出0即可

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef priority_queue<int, vector<int>, less<int>> Q;
#define x first
#define y second
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
const int N = 1e6 + 10;
ll a[N];
signed main()
{
    // freopen("in.in", "r", stdin);
    // freopen("out.out", "w", stdout);
    int n, k;
    cin >> n >> k;
    // 记录当前总共减去了多少
    ll ans = 0;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    sort(a + 1, a + n + 1);
    for (int i = 1; i <= n; i++)
    {
        // 如果当前已经被减完的话,就跳过当前这个数,因为每个数都要找大于0的
        a[i] = max(0ll, a[i] - ans);
        // 如果当前元素大于0,并且还需要操作的话就继续操作
        if (a[i] > 0 && k > 0)
        {
            // 操作次数减1
            k--;
            cout << a[i] << endl;
        }
        // 减去元素加上
        ans += a[i];
    }
    while (k--)
    {
        puts("0");
    }
    return 0;
}

C.AcWing 4496. 吃水果

题目

n 个小朋友站成一排,等着吃水果。

一共有 m 种水果,每种水果的数量都足够多。

现在,要给每个小朋友都发一个水果,要求:在所有小朋友都拿到水果后,恰好有 k 个小朋友拿到的水果和其左边相邻小朋友拿到的水果不同(最左边的小朋友当然不算数,即最左边的小朋友不包含在 k 个小朋友内)。

请你计算,一共有多少种不同的分发水果的方案。

思路: 状态机模型

根据闫氏dp法分析,总共有三个参数

状态表示f[i][j][k] 表是前i个小朋友,其中有j个小朋友被选中的总方案数,k==0时,表示第i个小朋友没被选中,k==1表示第i个小朋友被选中

状态计算

  • 当第i个小朋友没被选上时:f[i][j][0] = f[i-1][j][1] + f[i-1][j][0],如果当前小朋友没被选上,那么他一定要和前一个小朋友拿的水果一样,所以就等于前一个的方案数
  • 当第i个小朋友被选上时:f[i][j][1] = (f[i-1][j-1][0] + f[i-1][j-1][1]) * (m-1) ,因为选中的要和前一个不一样,所以方案数要乘上m-1

代码1

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef priority_queue<int, vector<int>, less<int>> Q;
#define x first
#define y second
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
const int N = 2010, mod = 998244353;
ll f[N][N][2];
ll n, m, k;
signed main()
{
    // freopen("in.in", "r", stdin);
    // freopen("out.out", "w", stdout);
    
    cin >> n >> m >> k;
    // 初始化,第一位置不能选,所以有m种水果可以选
    f[1][0][0]=m;
    for (int i = 2; i <= n; i++)
    {
        f[i][0][0] = f[i - 1][0][0]  % mod;
        for (int j = k; j >= 1; j--)
        {
            f[i][j][0] = f[i - 1][j][1]  % mod + f[i - 1][j][0]  % mod;
            f[i][j][1] = f[i - 1][j - 1][1] * (m - 1) % mod + f[i - 1][j - 1][0] * (m-1) % mod;
        }
    }
    ll ans = (f[n][k][1] + f[n][k][0]) % mod;
    cout << ans;
    return 0;
}

我们还可以优化,可以不用表示状态那一维。

01背包

状态表示f[i][j] 表是前i个小朋友,其中有j个小朋友被选中的总方案数

状态计算

  • 当第i个小朋友没被选上时:f[i][j] += f[i-1][j],如果当前小朋友没被选上,那么他一定要和前一个小朋友拿的水果一样,所以就等于前一个的方案数
  • 当第i个小朋友被选上时:f[i][j] += f[i-1][j-1] * (m-1) ,因为选中的要和前一个不一样,所以方案数要乘上m-1

代码2

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef priority_queue<int, vector<int>, less<int>> Q;
#define x first
#define y second
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
const int N = 2010, mod = 998244353;
ll f[N][N];
ll n, m, k;
signed main()
{
    // freopen("in.in", "r", stdin);
    // freopen("out.out", "w", stdout);

    cin >> n >> m >> k;
    f[1][0] = m;
    for (int i = 2; i <= n; i++)
    {
        f[i][0] = f[i - 1][0] % mod;
        for (int j = k; j >= 1; j--)
        {
            f[i][j] = (f[i - 1][j] + f[i - 1][j - 1] * (m - 1)) % mod;
        }
    }
    ll ans = f[n][k];
    cout << ans;
    return 0;
}
相关文章
|
6月前
|
存储
Leetcode第383场周赛
在LeetCode第383场周赛中,选手完成了3道题目。第一题是关于边界上的蚂蚁,蚂蚁根据非零整数数组nums的值移动,返回蚂蚁返回边界上的次数。解题方法是计算数组累加和为0的次数。第二题涉及计算网格的区域平均强度,给定一个灰度图像和阈值,返回每个像素所属区域的平均强度。解题关键在于理解相邻像素和区域定义,并计算平均强度。第三题是恢复单词初始状态的最短时间问题,通过移除前k个字符并添加k个字符,求恢复原词所需的最短时间。解题策略是检查去除前k个字符后的子串是否能作为原词的前缀。
34 1
Leetcode第383场周赛
|
6月前
|
存储
Leetcode第382场周赛
```markdown 给定字符串`s`,计算按键变更次数,即使用不同键的次数,不考虑大小写差异。例如,`&quot;aAbBcC&quot;`变更了2次。函数`countKeyChanges`实现此功能。另外,求满足特定模式子集最大元素数,`maximumLength`函数使用`TreeMap`统计次数,枚举并构建子集,返回最大长度。最后,Alice和Bob玩鲜花游戏,Alice要赢需满足鲜花总数奇数、顺时针在[1,n]、逆时针在[1,m],返回满足条件的(x, y)对数,可通过奇偶性分类讨论求解。 ```
36 1
|
存储 C语言 C++
【PAT甲级 - C++题解】1012 The Best Rank
【PAT甲级 - C++题解】1012 The Best Rank
48 0
|
测试技术
LeetCode283场周赛
LeetCode283场周赛
83 0
|
测试技术
洛谷P8601[蓝桥杯][2013年第四届真题]剪格子
洛谷P8601[蓝桥杯][2013年第四届真题]剪格子
78 0
AcWing第 96 场周赛
AcWing第 96 场周赛
187 0
|
算法 Java
acwing 第63场周赛【2022.08.06】
acwing 第63场周赛【2022.08.06】
80 0
acwing 第63场周赛【2022.08.06】