题解 | #2022牛客OI赛前集训营平民题解#

学习除法

https://ac.nowcoder.com/acm/contest/40639/A

T1: 学习除法

鸡尾酒的学生丹丹学不会除法,有一天他遇到了这样的一个问题:给定一个整数 nn,你可以任选一个 nn 的因子 xx,然后将 nn 除以 xx。你可以进行任意次这样的操作,直到 nn 是一个质数为止。请问至少几次操作可以让 nn 变成一个质数。

由于丹丹不会除法,更不知道因子是什么意思,所以他将这个问题交给你了,请你帮他解决这个问题。

例如:原数字 n=8n=8,选择 88 的因子 22,将 88 除以 22,此时 n=4n=4。然后再选择 44 的因子 22,将 44 除以 22,得到 n=2n=2。此时 nn 是一个质数。(这样的操作方案不一定是最优的,因为本题在求最少的操作次数)

大致思路,容易发现,如果 nn 是质数,不需要操作。如果 nn 是合数,总可以除一个数变成质数,所以只需要操作一次。

#include <bits/stdc++.h>
using namespace std;
 
#define int long long
int n;
 
bool check(int x) {
    for (int i = 2; i <= x / i; i++) {
        if (x % i == 0) return 0;
    }
    return 1;
}
 
signed main() {
    cin >> n;
    if (check(n)) puts("0");
    else puts("1");
}

T2: 拆分

鸡尾酒又带着大家学习新定义啦!今天要学习的内容是集合的 mexmex,集合的 mexmex 指的是一个集合没有出现过的最小自然数。例如,mex(1,2)=0mex({1,2}) = 0mex(0,1,2,3)=4mex({0,1,2,3}) = 4

现在你有一个包含 nn 个元素的集合,你可以将它分成任意个数量的新集合,使得所有新集合的 mexmex 值之和最大,求这个最大值是多少。

如果说划分的一个子集不包含 00,则其 mexmex00,也就是毫无贡献。只需要对所有 00 往上慢慢叠加计算贡献即可。只有 00 存在才有贡献!由于数据范围 1000\leq 1000,可以开桶!

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

#define int long long
const int N = 1e5 + 5;
int n, a[N], cnt[N], t, res;

signed main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        if (a[i] == 0) t++;    // 计算0的数量
        else cnt[a[i]]++;  // 开个桶
    }
    while (t--) {   // 来t次就可以了
        int j = 1;
        for (j = 1; j <= 1001; j++) {     // 找到第一个数不存在
            if (cnt[j]) cnt[j]--;   // 如果有,在桶里面减
            else break;
        }
        res += j;   // 加贡献
    }
    cout << res << endl;
}

T3: 部落

在一个山峰中住着许多部落,其中一些部落住在山脚,一些部落住在山腰,一些部落住在山顶。我们假设共有 n\mathit n 个部落,编号分别为 1,2,3,...,n1,n1,2,3,...,n-1,n,且第 pos\mathit pos 个部落的位置在山顶。那么编号为 1pos1 \sim pos 的部落海拔依次上升,从 posnpos \sim n 的部落海拔依次降低。第 i\mathit i 个部落和第 i+1,i1\mathit i+1, i-1 个部落相邻 (2in1)(2 \leq i \leq n-1)

由于山中常年缺水,主要的水资源是山间的流水,具体来说,水资源都聚集在山顶,海拔较低的部落只能使用海拔较高的部落用剩下的水资源。由于分配不均,相邻的部落之间可能会发生战争,其中第 ii 个部落的战斗力为 aia_i

当某一个部落的海拔比另一个相邻部落的海拔低,且战斗力比这个部落高,则会对这个部落发动战争。

现在为了避免相邻部落之间发生战争,你可以修改一些部落的战斗力,使得每一对相邻的部落之间都不会有战争。请问最少可以修改几个部落的战斗力才可以满足要求?

可以知道这道题是一个 LIS 问题。从 11pospos 求一遍 LIS,再从 posposnn 求一遍下降子序列。但是由于双方有重复部分 pospos,所以考虑最上面那一个点是否需要修改高度!否则都算一遍会多答案。

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

const int N = 1e5 + 5;
int n, pos, a[N], g[N], cnt, res;

int main() {
    cin >> n >> pos;
    for (int i = 1; i <= n; i++) cin >> a[i];
    g[++cnt] = a[1];
    for (int i = 2; i < pos; i++) {
        if (a[i] >= g[cnt]) g[++cnt] = a[i];
        else g[lower_bound(g + 1, g + cnt + 1, a[i]) - g] = a[i];
    }
    if (a[pos] >= g[cnt]) cnt++;  // 不需要修改
    else a[pos] = 1e9;  // 需要修改就厉害点,正无穷
    res += pos - cnt;
  
    cnt = 0;   // pos~n求一遍
    g[++cnt] = a[n];
    for (int i = n - 1; i >= pos; i--) {
        if (a[i] >= g[cnt]) g[++cnt] = a[i];
        else g[lower_bound(g + 1, g + cnt + 1, a[i]) - g] = a[i];
    }
    res += (n - pos + 1) - cnt;
    cout << res << endl;
}

全部评论

相关推荐

身边的人都在收获,我却还在原地踏步,到底该怎么办啊!每次看到他们的好消息,我都想放弃,心里不停地问自己:到底该怎么才能找到一份工作呢?这种无力感让我想要彻底摆烂,真的很想知道,别人是怎么做到的。有没有人分享一下经历呢?我想学习一下啊走出这样的日子。
鼗:秋招其实是运气>实力的一场竞技游戏,除非实力很强(学历和技术)。大多数人都是半斤八两,看面试官和HR以及简历被曝光的概率罢了,有些时候你可能运气差一点或者说面试官不太友好也或者说你确实准备的不够好之类的,这些都是可能发生的事情。我觉得能做的事情是不比较、不气馁、在面试前多看一点面试的时间冷静一点自信一点,大大方方面试,给自己多一点时间去求职。我这样说不是站着说话不腰疼,我是想说你的offer还在路上,你也值得在这些困难之后得到你较为理想的offer,请你继续加油,保持乐观,积极打败你现在的困难
点赞 评论 收藏
分享
去B座二楼砸水泥地:不过也可以理解,这种应该没参加过秋招
点赞 评论 收藏
分享
11-07 13:22
已编辑
博尔塔拉职业技术学院 Java
再也不用京东买东西了,之前给别人买礼物啥的都用的jd,还是用的群友的内推!
一定要上岸的安迪很有胆量:排序挂吗?
投递京东等公司10个岗位 > 秋招joker
点赞 评论 收藏
分享
6 收藏 评论
分享
牛客网
牛客企业服务