考的时候完全没想到这个方法,算法知识储备过于贫瘠。记录一下。
题目链接
思路
m
最大到100000,暴力法n
次遍历就超时了
因此需要先根据y
值(安全指数)从小到大排序,再用类似前缀和的方法计算出每一个输入,它之前(安全系数y
比他小)result
为0的数的个数,以及它之后(安全系数y
比它大)result
为0的数的个数,两者之和就是我们想比较的sum
。这种方法算sum
只需遍历2遍,正着一遍求0,逆着一遍求1。
最后找到最大的sum
值对应的最大安全指数y
就是输出结果。
前缀和
最简单的一个例子就是给定 n 个数和 m 次询问,每次询问一段区间的和。求一个 O(n + m) 的做法。
如果这n个数就是1~100,
那么sum数组里依次存放的就是1,(1+2),(1+2+3),…,(1+2+…+100),创建sum数组的过程一次遍历即可完成。
然后如果想知道任何一段区间的和,比如3~48的和,只需sum[48]-sum[2]
//核心代码
for(int i = 1; i <= n; ++i)
sum[i] = sum[i - 1] + a[i]; //O(n)
while(m--) //O(m)
{
int L, R;
scanf("%d%d", &L, &R);
printf("%d\n", sum[R] - sum[L - 1]);
}
题目代码
#include <iostream>
#include <algorithm>
using namespace std;
struct Mypair{
int y;
int result;
int before;
int after;
int sum;
};
Mypair array[100000];
int cmp(Mypair pair1, Mypair pair2){
return pair1.y < pair2.y;
}
int cmp2(Mypair pair1, Mypair pair2){
if(pair1.sum == pair2.sum)
return(pair1.y>pair2.y);
else{
return pair1.sum>pair2.sum;
}
}
int main(){
int m;
scanf("%d",&m);
for(int i = 0;i<m; ++i){
scanf("%d %d",&array[i].y,&array[i].result);
}
sort(array,array+m,cmp);
//求before,正着遍历一遍
array[0].before = 0;
int preY = array[0].y;
int preIndex = 0;
for(int i = 1;i<m;++i){
if(array[i].y == preY){
//对于类似(3 0)(3 1)(3 0)的数据的处理
array[i].before = array[i-1].before;
}else{
int tsum = 0;
for(int j = preIndex;j<i;j++){
tsum += array[j].result == 0 ? 1:0;
}
array[i].before = array[i-1].before + tsum;
preY = array[i].y;
preIndex = i;
}
}
//求after,逆着遍历一遍
array[m-1].after = array[m-1].result == 1?1:0;
array[m-1].sum = array[m-1].before + array[m-1].after;
preY = array[m-1].y;
preIndex = m-1;
for(int i = m-2;i>=0;i--){
if(array[i].y == preY){
array[i].after = array[i+1].after;
}else{
int tsum = 0;
for(int j = preIndex;j>i;j--){
tsum += array[j].result == 1?1:0;
}
array[i].after = array[i+1].after + tsum;
preY = array[i].y;
preIndex = i;
}
array[i].sum = array[i].before + array[i].after;
}
// for(int i = 0;i<m;i++){
// printf("y: %d before:%d after:%d\n",array[i].y,array[i].before,array[i].after);
// }
sort(array,array+m,cmp2); //根据sum和y排序
printf("%d",array[0].y);
return 0;
}