Acwing 第 86 场周赛题解

在这里插入图片描述

老年手速(o(╥﹏╥)o),该电电了

因为代码的风格,题目中的longlong问题不再考虑(自动longlong)

AcWing 4794. 健身

原题连接

模拟

#include <bits/stdc++.h>

using namespace std;

#define int long long

signed main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int n;
    std::cin >> n;
    std::vector<int> a(n + 1);
    int x = 0,y = 0,z = 0;
    for (int i = 1; i <= n; i ++) {
        int t;
        std::cin >> t;
        if (i % 3 == 1) x += t;
        else if (i % 3 == 2) y += t;
        else z += t;
    }
    int max = std::max({x,y,z});
    if (max == x) std::cout << "chest\n";
    else if (max == y) std::cout << "biceps\n";
    else std::cout << "back\n";
    return 0;
}

AcWing 4795. 安全区域

原题连接

思路

分类讨论:
1.首先总数是n*n个
2.如果当前的位置横竖都没有车,那么它的行将受到攻击,列将收到攻击,那么就会减少n * n - 1个
3.如果这一 上没车但是这一 上有车,列不减少,那么行减少(n - 被占据的列的个数);
4.如果这一 上没车但是这一 上有车,行不减少,那么列减少(n - 被占据的行的个数);

代码实现

我们需要分别记录行,列占据的个数,然后模拟判断即可,具体看代码

#include <bits/stdc++.h>
using namespace std;

#define int long long
using PII = pair<int,int>;

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    int n,m;
    std::cin >> n >> m;
    int t1 = n,t2 = n;//行列起始各有多少个
    std::vector<bool> a(n + 1),b(n + 1);//a为行,b为列
    int res = n * n;//总的个数
    for (int i = 1; i <= m; i ++) {
        int x,y;
        std::cin >> x >> y;
        if (!a[x]) {//当前行没有被占据
            a[x] = true;
            res -= t1;//减去当前行的格子的数量
            t2 --;//某一行被去掉的话,那么每列格子的数量会减1
        }
        if (!b[y]) {//当前列没有被占据
            b[y] = true;//减去当前列的格子的数量
            res -= t2;//某一列被去掉的话,那么每行格子的数量会减1
            t1 --;
        }
        std::cout << res << " \n"[i == m];
    }
    return 0;
}

AcWing 4796. 删除序列

原题连接

思路

题目问的是最大得分,某个数的总的得分等于这个数 * 它的数量。 由于我们选了一个数之后一定会把他选空,因此只看总的价值即可。

解题

由此,题目就变成了怎样选数,使得最后答案最大。 看到这几乎就可以断定这是一道DP

新题意

1.选择 x, 那么x - 1 和 x + 1就不能选
2.不选 x, 选x - 1 或 x + 1 或 两个我都要(_)

于是状态转移
选x的话,那么它的价值要比另外两个的和要打,不然我就不选
不选x, 那么x - 1 和 x + 1都要
f[i] = f[i - 1];
or
f[i] += f[i - 2];

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int N = 100010;
 
int c[N];
int f[N];

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr); 
    int n;
    std::cin >> n;
    for (int i = 0; i < n; i++) {
        int x;
        std::cin >> x;
        c[x]++;
    }
    f[0] = 0ll;
    for (int i = 1; i < N; i++) {
        f[i] = i * c[i];
        if (i - 2 >= 0) {//可以选x - 1的范围
            f[i] += f[i - 2];//选x - 1 与 自己(x + 1)
        }
        if (f[i - 1] > f[i]) {//比较 选 x 的价值
            f[i] = f[i - 1];
        }
    }
    std::cout << f[N - 1] << endl; //由于数据的问题,不能保证答案一定在f[n],所以取最后边的
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值