【Codeforces Round #767 (Div. 2) 】C. Meximum Array 题解

1629C: Meximum Array 题解

  • 【Codeforces Round #767 (Div. 2) 】C. Meximum Array 题解
    • 一、题目描述
      • (一)、原题链接
      • (二)、题目大意
    • 二、题解思路
    • 三、注意事项
      • (一)、在标记数组中删除前面的元素时的边界问题
      • (二)、在求MEX时进行处理避免特殊数据导致TLE
    • 四、代码全览

一、题目描述

(一)、原题链接

原题链接:https://codeforces.com/contest/1629/problem/C

(二)、题目大意

有多组测试数据,每组数据给出一个长度为n的元素在[0, n]内的数组。

定义一串数的MEX值为从0开始该串数中第一个缺少的数。例如MEX({2, 3, 1, 0, 5}) = 4。

整个题目的意思就是找出数组中最大的MEX值,然后将满足最大MEX值的从左往右的找连续的最小子段满足该字段MEX和最大的MEX值相同。找见之后存储当前的MEX值,剩下的字串就有了新的MEX值,然后再按上面的过程重复,直到找完整个数组。

最后输出这一串MEX值的个数和这串MEX值。

下面是单组测试数据的例子:

二、题解思路

如何求解MEX值呢?可以事先把数组中出现的数进行标记出个数。然后从0开始往上遍历,如果个数为0则证明没有这个数,也就是目前的MEX值。

int getMEX(int cnt[], int preTry)
{for (int i = preTry; ; i++)if (cnt[i] == 0)return i;
}

然后解题就容易了,提前先求一遍MEX值作为标准,然后从左往右按元素进行标记,标记一次求一次MEX,与标准比较,相同则截断存储答案,然后删去元素,继续找下一个答案。

int tempMEX = getMEX(src, 0);   // 计算源数组的MEX值
int pre = -1;
int pretry = 0; // 存储临时数组的MEX值的位置
for (int i = 0; i < n; i++)
{temp[a[i]]++;// 如果当前MEX和数组MEX相同,则从此处断开if ((pretry = getMEX(temp, pretry)) == tempMEX){ans[anslen++] = tempMEX;    // 保存答案for (int j = pre + 1; j <= i; j++)  // 恢复标记数组{src[a[j]]--;temp[a[j]]--;}pre = i;tempMEX = getMEX(src, 0);   // 计算新的数组MEX值pretry = 0; // 初始化临时数组MEX值}
}

三、注意事项

(一)、在标记数组中删除前面的元素时的边界问题

为了不重不漏,所以采取了左闭右开的结构。每次从之前的后一个开始删,然后删到当前(包括当前元素)。

(二)、在求MEX时进行处理避免特殊数据导致TLE

即用一个变量记录当前求出的MEX,在这个周期内再次求MEX时直接从当前MEX开始往后遍历就好了。

四、代码全览

// Meximum Array
#include <iostream>
#define DEBUG
#define N 200050
using namespace std;// 读取的原数组 | 原数组的标记数组 | 临时的标记数组 | 原数组长度 | 答案数组 | 答案长度
int a[N], src[N], temp[N], n, ans[N], anslen;
int getMEX(int cnt[], int preTry);  // 得到标记数组内最小的未标记数
void solve(void);   // 单组测试数组的解决int main(void)
{int test;cin >> test;while (test--)solve();return 0;
}// 单组测试数组的解决
void solve(void)
{anslen = 0; // 初始化答案长度cin >> n;// 读取原数组数据并对其做标记for (int i = 0; i < n; i++){cin >> a[i];src[a[i]]++;}int tempMEX = getMEX(src, 0);   // 计算源数组的MEX值int pre = -1;int pretry = 0; // 存储临时数组的MEX值的位置for (int i = 0; i < n; i++){temp[a[i]]++;// 如果当前MEX和数组MEX相同,则从此处断开if ((pretry = getMEX(temp, pretry)) == tempMEX){ans[anslen++] = tempMEX;    // 保存答案for (int j = pre + 1; j <= i; j++)  // 恢复标记数组{src[a[j]]--;temp[a[j]]--;}pre = i;tempMEX = getMEX(src, 0);   // 计算新的数组MEX值pretry = 0; // 初始化临时数组MEX值}}// 输出结果cout << anslen << endl;for (int i = 0; i < anslen; i++)cout << ans[i] << " ";cout << endl;
}// 得到标记数组内最小的未标记数
// cnt[] : 标记数组
// pretry : 上次得到的尝试值, 如果不在一个逻辑内, 值应置为0
int getMEX(int cnt[], int preTry)
{for (int i = preTry; ; i++)if (cnt[i] == 0)return i;
}

【Codeforces Round #767 (Div. 2)】 C. Meximum Array 题解相关推荐

  1. Codeforces Round #727 (Div. 2) F. Strange Array 线段树 + 区间合并 + 排序优化

    传送门 文章目录 题意: 思路: 题意: 给你一个长度为nnn的数组,对每个位置iii求一个最大价值,价值计算方式如下:选择一个包含iii的[l,r][l,r][l,r],让后将其拿出来排序,之后价值 ...

  2. Codeforces Round #807 (Div. 2)A~E个人题解

    Dashboard - Codeforces Round #807 (Div. 2) - Codeforces A. Mark the Photographer 题意: 有个人,每个人的身高设为,现在 ...

  3. Codeforces Round #706 (Div. 2)-A. Split it!-题解

    目录 Codeforces Round #706 (Div. 2)-A. Split it! Problem Description Input Output Sample Input Sample ...

  4. Codeforces Round #767 (Div. 2)题解

    这里写目录标题 A Download More RAM 题解 代码 B GCD Arrays 题目 题解 计算奇偶数的办法 代码 C Meximum Array Mex (mathematics) 题 ...

  5. Codeforces Round #742 (Div. 2) B、C 题解

    Codeforces Round 742 B. MEXor Mixup 题意 有一个数组,输入两个数a,b,a代表这个数组之外的最小非负整数,b代表这个数组的异或值,问你该数组的最小长度. 思路 首先 ...

  6. Codeforces Round #702 (Div. 3)——A. Dense Array

    A. Dense Array 题意 T组测试样例,每组n个数据,问最少需要在当前这组数据中插入多少个数使得当前的这组数据满足相邻两个数据之间的最大值与最小值的比值小于等于2. 测试样例解释 input ...

  7. Codeforces Round #577 (Div. 2)--B. Zero Array

    菜鸡我认为的好题 题意:这里有n个数,两两相互减1,执行n次,问有没有可能这n个数全都变为0; 做法:首先和是奇数是不可能的,然后和为偶数的时候:比如数据 2 2 6 那么结果是不可以的,变 -> ...

  8. Codeforces Round #650 (Div. 3)(A-F1)题解

    A. Short Substrings 题解:按题意模拟即可 /*Keep on going Never give up*/ #pragma GCC optimize(3,"Ofast&qu ...

  9. 【Codeforces Round #784 (Div. 4)】【AK题解】

    2022年4月30日19:43:21 文章目录 2022年4月30日19:43:21 A. Division? 题目描述 测试样例 题解 B. Triple 题目描述 测试样例 题解 C. Odd/E ...

最新文章

  1. css rem 大屏开发_px和em、rem单元如何选择?
  2. python spider 安装_Python爬虫(11):Scrapy框架的安装和基本使用
  3. UOJ #214 [UNR #1]合唱队形 (概率期望计数、DP、Min-Max容斥)
  4. tensorflow从入门到放弃(三)
  5. SpringBoot_数据访问-整合MyBatis(一)-基础环境搭建
  6. sql中count(1)、count(*)和count(字段名)的区别
  7. python 学习第四十七天shelve模块
  8. nodejs websocket server
  9. (6)<a>标签如何实现点击既不刷新也不跳转的功能
  10. 2006. 差的绝对值为 K 的数对数目
  11. iOS中的所有字体和UILabel
  12. 程序员30多岁了还单身的原因
  13. matlab 隶属度计算,基于MATLAB实现的云模型计算隶属度
  14. Unable to add window android.view.ViewRootImpl$W@c1bf05d -- permission denied for window type 2003
  15. Mac小白用户看过来,教你这样卸载Mac应用程序
  16. 60 Linux 常用 命令
  17. 从认知智能的角度认识ChatGPT的不足
  18. 分享一款快速、免费抠图工具——凡科快图
  19. 不等式$\sum x_i^3(1-x_i)\leq\frac{1}{8}$
  20. LeetCode 587. 安装栅栏【凸包算法】【C++】【很多坑】

热门文章

  1. foo php,php – $foo === TRUE和TRUE === $foo有什么区别?
  2. 跨网段实现内网互通_【供暖站组网】冠航SD-LAN助力河北石家庄市30个供暖站异地组网实现内网互联互通...
  3. 九九乘法表用python怎么写_用python做个九九乘法表
  4. 内存分配_go内存分配管理
  5. python怎么捕获mysql报错
  6. 目标检测R-CNN模型的CNN模块微调过程分析【全网最易懂】
  7. SQLite数据库简介
  8. (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法
  9. at指令 fpga_FPGA毕设系列 | 无线通信
  10. aix oracle 登录用户,AIX 系统及 Oracle 数据库用户权限管理