这道题使用两层暴力循环会超时,第二次才拿满了分数
第一次的代码(70分):
思路非常简单,建立一个长度为n的结构体,每个结构体包含三个数值,y、result、以每个y为标准判断的正确次数right。
两个for循环嵌套求出每个y。
快排(优先级:right较大->y较大),输出第一个结构体的y值。
//由于使用了两层循环,会有部分样例超时。
#include<iostream>
#include<algorithm>
using namespace std;
struct classmate{
int y;
int result;
int right;
classmate():y(0),result(0),right(0){
}
};
bool compare(const classmate& a,const classmate& b){
if(a.right!=b.right)
return a.right>b.right;
else if(a.y!=b.y)
return a.y>b.y;
return 0;
}
int main(){
int n;
cin>>n;
classmate student[n];
for(int i=0;i<n;i++){
cin>>student[i].y;
cin>>student[i].result;
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(student[i].y>student[j].y&&student[j].result==0){
student[i].right++;
}
else if(student[i].y<=student[j].y&&student[j].result==1){
student[i].right++;
}
}
}
sort(student,student+n,compare);
cout<<student[0].y<<endl;
}
第二次(100分):
思路也很简单,当我们将所有个体按照y从小到大的顺序排序时,每个结构体的right值都与前一个关系很大。
所以先将结构体数组按照y从小到大的顺序排序。
我们可以知道,每个结构体单元(除了第一个)与前一个结构体单元的关系只有两种:y相等,y大于。
1、当y相等时,这时由于y值一样,所以他们预测结果的正确数量也相同,直接将前一个的right赋给他即可。
2、当y大于时,如果前面的(假如y不是重复数)的right值为1,我们要减掉1才能将前一个right赋给他;同理,如果是0,则加1。
但是前面的数(y)可能是一堆重复数(比如:1 2 2 2 5,5前面就是一堆重复数),这个时候我们通过zero记录这些重复数中result为0的个数,one记录这些重复数中为1的个数。我们只需要仿照没有重复数的时候,前一个的right减去one加上zero即可。
每次当结构体单元的y值与前一个不同时,即对zero和one进行初始化。
#include<iostream>
#include<algorithm>
using namespace std;
struct classmate{
int y;
int result;
int right;
classmate():y(0),result(0),right(0){
}
};
bool compare1(const classmate& a,const classmate& b){
if(a.right!=b.right)
return a.right>b.right;
else if(a.y!=b.y)
return a.y>b.y;
return 0;
}
bool compare2(const classmate& a,const classmate& b){
if(a.y!=b.y)
return a.y<b.y;
return 0;
}
int main(){
int n;
cin>>n;
classmate student[n];
for(int i=0;i<n;i++){
cin>>student[i].y;
cin>>student[i].result;
}
sort(student,student+n,compare2);
//按照y值从小到大的顺序排序
int zero=0,one=0;
for(int i=0;i<n;i++){
if(i==0){
for(int j=0;j<n;j++){
if(student[i].y>student[j].y&&student[j].result==0){
student[i].right++;
}
else if(student[i].y<=student[j].y&&student[j].result==1){
student[i].right++;
}
}
if(student[i].result==0){
zero=1;
}
else{
one=1;
}
}
//先把第一个单元的各种数值计算出来
else if(student[i].y==student[i-1].y){
student[i].right=student[i-1].right;
if(student[i].result==0){
zero++;
}
else{
one++;
}
}
//相等的情况,直接继承right值即可,然后对zero和one进行计数
else{
student[i].right=student[i-1].right-one+zero;
if(student[i].result==0){
zero=1;
one=0;
}
else{
zero=0;
one=1;
}
}
//不相等的情况,将上一个的right值减one加zero即可,别忘了对one和zero初始化
}
sort(student,student+n,compare1);
//按照题目要求,以right值为第一优先级,从大到小排序
//以y值为第二优先级,从大到小排序
cout<<student[0].y<<endl;
//输出第一个的y值即可
}