小明和完美序列
最近做了这道题 给大家看看我一开始写的代码 这个时候刚学完二分和vector动态数组偶然看见了这个题然后就兴冲冲的用二分去写
上下两个代码一个用的是数组一个用的是vector其他的没啥区别
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int a[N];
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n;
cin >> n;
for(int i = 0;i < n;i ++){
cin >> a[i];
}
sort(a,a + n);
int s = 0;
for(int i = 0;i < n;i ++){
int g = 0;
g = upper_bound(a,a + n,a[i]) - lower_bound(a,a + n,a[i]);
//g为数组中一个相同数字出现的次数
if(g != a[i]){
s ++;
}
}
cout << s << '\n';
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
vector<int> arr;
int n;
cin >> n;
for(int i = 0;i < n;i ++){
arr.push_back(i);;
}
sort(arr.begin(),arr.end());
int s = 0;
for(int i = 0;i < n;i ++){
int g = 0;
g = upper_bound(arr.begin(),arr.end(),arr[i]) - lower_bound(arr.begin(),arr.end(),arr[i]);
//g为数组中一个相同数字出现的次数
if(g != arr[i]){
s++;
}
}
cout << s << '\n';
return 0;
}
细心的同学们肯定看到了这个第二段代码写的什么东西....push_back(i)把 i一个一输入进去(当时对push_back这个玩意的语法还不熟悉 写数组遍历习惯了就这么写vector的遍历了)当时一提交还通过了俩案例
我心想哎哟我靠我这么牛呢 别人都用map 我没学map都写出来了
之后我又提交了第一段的代码 结果
甚至通过了一大半的案例.....我当时真的觉得没有人比我更懂二分.....
标准题解(附代码注释)
#include <bits/stdc++.h> // 引入标准库的所有头文件
using namespace std; // 使用标准命名空间
typedef long long LL; // 定义长整型别名 LL
int main() // 程序入口
{
int n; // 声明整型变量 n
cin >> n; // 从标准输入读取 n 的值
vector<int> a(n + 1); // 声明整型向量 a,大小为 n+1
map<int, int> cnt; // 声明一个映射,键为整数,值为整数,用于统计每个数出现的次数
// 循环读入 n 个整数,并更新 cnt 中每个数的出现次数
for(int i = 1; i <= n; i ++) {
cin >> a[i];
cnt[a[i]] ++;
}
int ans = 0; // 初始化答案为 0
// 遍历 cnt 中的每个键值对,键为数值,值为出现次数
for(auto [x, y] : cnt) {
// 如果某个数出现的次数大于该数值本身,说明需要删除多余的数
if(y > x)
ans += y - x; // 删除多余的数,并将删除的数目累加到答案中
// 如果某个数出现的次数小于该数值本身,说明所有该数都需要被删除
else if(y < x)
ans += y; // 将该数出现的次数累加到答案中
}
cout << ans; // 输出答案
}
注意这里的cnt[a[i]]++可能第一次见的同学们不太理解
咱们要把map去理解成数学中f(x)的形式 一个x值只能对应一个y值
此时相当于是把map中a[i]所对应的值取出并自增1 类比函数就是从(1,0)→(1,1)
漏洞指出
不知道我这样想的是不是个例吧 时候了解完审视了一遍自己的代码之后发现
1.s的值并不是累加而是重复赋值
在每一次的for循环里面都会进行一次重新的赋值而不是累次加起来
2.讨论范围受限
只讨论了如果测试数据中只有一个数字不满足完美序列要求的时候且这个数字一定在这一组数据的最后端的部分出现(因为第一点的s的值重复赋值进去了所以只取最后一次赋给s的值)
3.vector中添加元素使用错误
第一段代码中咱们看个笑话就行
正常来写应该是
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
vector<int> arr;
int n;
cin >> n;
int a;
for(int i = 0;i < n;i ++){
cin >> a;
arr.push_back(a);;
}
以上这样才是一个正常遍历去添加vector数组中的元素的步骤
对蓝桥OJ题目的碎碎念
测试数据未免太水了。。。。
现在看起来我当时就是在纯纯的瞎写还能通过这么多案例
有一种把你捧到天上之后之后摔碎的落差感。。。
当时我甚至还坐在电脑前思考这一系列的逻辑问题(十分坚定的相信自己的二分写法。。。)