题目描述
输入与输出
样例
源代码
#include<iostream>
#include<algorithm>
using namespace std;
pair<int, int> n[100005]; //每个pair存储一个同学的y和result
int re0[100005]; //记录该位置及前面的result为0的个数
int re1[100005]; //记录该位置及后面的result为1的个数
int num = -1,v = 0; //num用来记录成功数目 v来记录最佳阈值
int main() {
int m;
cin >> m;
n[0] = pair<int, int>(-1, -1);
for (int i = 1; i <= m; ++i)
cin >> n[i].first >> n[i].second;
sort(n + 1, n + 1 + m); //将阈值从小到大排序 不排n[0]因为我们将其初始化为-1 并且我们是直接从n[1]开始取用的
for (int i = 1; i <= m; ++i) //因为是不包括当前数的0的 所以取用re0[i-1]
if (n[i].second == 0)
re0[i] = re0[i - 1] + 1;
else
re0[i] = re0[i - 1];
for (int i = m; i >= 1; --i) //因为包括当前数的1 所以直接用re1[i]即可
if (n[i].second == 1)
re1[i] = re1[i + 1] + 1;
else
re1[i] = re1[i + 1];
for (int i = 1; i <= m; ++i) {
if (n[i].first == n[i - 1].first)
continue; //如果有yi 相同的情况 阈值已经取用过1次 就不用再取 可以直接跳过
if (num <= re0[i - 1] + re1[i])
num = re0[i - 1] + re1[i], v = n[i].first;
}
cout << v;
return 0;
}
关于这题
题目说明了:
所以暴力遍历 可以完成70% 最后30%很有可能会超时
所以这里优化一下
0 1 (阈值取用)
pre 1 0 re 0
1 1 0
1 1 1
1 1 1
1 1 1
1 1 1
升序之后 阈值前面的数 pre都为0 后面的数包括他自己 pre都为1
所以实际上我们只需要统计 阈值前面0的个数和后面包括自身1的个数
这里我举了样例1中阈值取用0 和 1 的例子
0后面四个1 前面没有0 总计为4 结果与re相同的数目也为1
1后面四个1 前面1个0 总结为5 结果也相符
每个pair存储一个同学的y和result
re0数组用来记录该位置及前面的result为0的个数
re1数组记录该位置及后面的result为1的个数
num用来记录成功数目 v来记录最佳阈值
num = re0[i - 1] + re1[i]
这样写是因为 取用时 不包括当前位置的0 包括当前位置的1