题目传送门
注意,时间限制 300ms,不要超时了。
题目解析
-
第一步:读入。
-
第二步:看看最小的未出现的非负整数有没有超过 k k k,如果没有,输出 0 0 0,结束程序;如果有,继续。
-
第三步:输出数组中小于等于 k k k 的数中出现次数最少的数的出现次数。
直接模拟即可。
代码历程
1版
#include <iostream>
#include <cstdio> // scanf 和 printf 要用
#include <climits> // INT_MAX 要用
using namespace std;
int n, k, a[1000], t = INT_MAX, b[10], l = 10; // t 表示答案,初始要设为极大值,用于与其他数取最小值。显然,出现次数最多的数的出现次数不会大于 INT_MAX(2147483647)。
// 数组 b 用来储存数组 a 中每个数字出现的次数。
// l 表示查找到后数字的下标,初始设为 10,一个特殊数字,用来标记有没有在循环中查找到小于等于 k 的非负整数。
int main() {
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i++) scanf("%d", &a[i]), b[a[i]]++;
for (int i = 0; i <= k; i++) if (!b[i]) { // 如果找到没有超过 k 的未出现的非负整数,就退出(这个数一定是最小的)。
l = i;
break;
}
if (l < 10) { // 如果有查找到,直接输出 0。
printf("0\n");
return 0;
}
for (int i = 0; i <= k; i++) t = min(t, b[i]); // 否则看看删除那个数用的次数最少,就是答案。
printf("%d\n", t);
return 0;
}
2版
发现可以优化哦。
#include <iostream>
#include <cstdio>
#include <climits>
using namespace std;
int n, k, a[1000], t = INT_MAX, b[10];
int main() {
scanf("%d%d", &n, &k);
for (int i = 0; i < n; i++) scanf("%d", &a[i]), b[a[i]]++;
for (int i = 0; i <= k; i++) t = min(t, b[i]);
printf("%d\n", t);
return 0;
}
这么说来,其实就是看看数组 b b b 中 b 0 , b 1 , b 2 , . . . , b k b_0,b_1,b_2,...,b_k b0,b1,b2,...,bk 中的最小值。
数组 b b b 中 b 0 , b 1 , b 2 , . . . , b k b_0,b_1,b_2,...,b_k b0,b1,b2,...,bk 若有 0 0 0,输出是 0 0 0,符合要求;若没有 0 0 0,则输出 b 0 , b 1 , b 2 , . . . , b k b_0,b_1,b_2,...,b_k b0,b1,b2,...,bk 中的最小值,也就是最少删除数字的次数。

200

被折叠的 条评论
为什么被折叠?



