题目:
链接:http://118.190.20.162/view.page?gpid=T122
接下来说一下做这道题的过程,刚开始只有70分,然后改完以后变成60分,最后到80分,100分,这里的时间复杂度为O(nlogn)主要是用于排序
然后说一下每一步没有拿满分的过程:
对于这道题要算成预测正确的次数就应该包括小于该值时不及格的次数加上大于等于该值时成功的个数,为了使计算更加简洁,执行步骤如下
- 在读入时记录下成功情况的总个数
- 对所有数据按照从小到大进行排序
- 在一次for循环中先看是否有两个值相同的数,如果发现两个值相同,则记录下所出现的0和1的次数,然后接着往下搜索
- 当出现值不相同的时候开始对数据进行处理,因为成功次数等于小于该数的值出现0的次数加上大于等于该数的值出现1的个数,而我们在读入的时候已经统计了出现1的总个数,这里只需要把出现1的总个数减去小于这个数时出现1的个数就可以得出大于等于该数的1也就是成功的次数,大于等于时成功次数和小于时失败的个数相加就可以统计出成功的次数,而在这里引入两个标记位,一个用于记录预测正确的次数最多的值,另一个数据用来记录次数最多时对应的阈值是多少。
- 经过一个for循环就可以得出最佳阈值并输出。
这里解释一下从70分到80分的过程,当出现两个值相同时,如
1 0
1 1
不能在计算1,1时错误的因为1,0在1,1之前就计算成比1,1小的值的失败就算预测成功,实际这次不能算在成功的次数里。所以需要在第三部中对相同的数预先进行一次处理。
接下来从80分到100分的过程,这里我刚开始以为的是既然要预测结果最高,肯定这个最高阈值应该出现在result值为1的地方,然后就只对result为1的情况进行搜索,结果就只有80分了。举个简单的例子,如果所有的result的值都为0,那么实际输出的值应该是最大的y,因为最大的y的时候小于y的都算是他成功的次数,所以这里不能只对result等于1进行计算,还要计算result等于0时成功的次数进行比较,这样就得了满分了。
代码如下:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
//将数据存储在结构体中
struct node{
long long y;
int result;
};
//用于进行排序,按从小到大,如果相等就按照结果为0,1来排序
bool cmp(node a,node b){
if(a.y<b.y)return true;
else if(a.y==b.y)return a.result<=b.result;
else return false;
}
int main(){
int n;
cin>>n;
vector<node>results;
int pass=0,unpass=0;
for(int i=0;i<n;i++){
node value;
//输入为安全指数和结果,是计算预测正确次数。大于等于表示不会挂科 ,
cin>>value.y>>value.result;
if(value.result!=0)
pass++;
results.push_back(value);
}
sort(results.begin(),results.end(),cmp);//注意在使用排序的时候如果是vector形式,只能用.begin()和.end()形式
int max=0,k=0;
int unpass2=0,pass2=0;
int temp0=0,h1=0;//记录下所有0和1的个数
for(int i=0;i<n;i++){//要统计出他前面都是0的个数和后面都是1 的个数
//处理好这个if循环从70到80
if(i<n-1&&results[i].y==results[i+1].y){
temp0+= (!results[i].result);//统计出值相同的情况下结果为1和为0 的个数各出现多少次
h1+=results[i].result;
continue;
}
if(results[i].result==0){ //这样会忽略一种情况,如果所有数都是0
int all=unpass2+(pass-pass2-1) ;//减去自己也输的情况
if(all>=max) {//在等于0的时候也要进行预测成功的计算从80分到100分
max=all;k=results[i].y;
}
unpass2+=1;//这里一定要加在计算完以后
}else{
int all=unpass2+(pass-pass2);
if(all>=max) {
max=all;k=results[i].y;
}
pass2+=1;//这里一定要加在计算完以后 ,因为该值等于的时候为1也算成功,前面是用总次数减去小于该数时成功的次数哦
}
pass2+=h1;unpass2+=temp0;//加上出现相同值是为1和为0的情况
h1=0,temp0=0;
}
cout<<k;
return 0;
}