程序设计竞赛的参赛队伍通常由3人组成。G队长从PTA下载了计算机专业全体学生的刷题成绩,想从中选出三名学生组成一支最强队伍。成绩单只列出了每位学生的学号和成绩,按学号从小到大排列。显然,最简单的方法是直接找出成绩排名前三的学生,但选出的学生可能集中在个别班级里,对其他班级有失公平;较公平的方法是先从每个班选成绩最好的,再从中筛选三人,但必须知道分班的情况。队长思索了半响,突然想到虽然每个班级的学生人数有出入,但上限是固定的,并且同一个教学班的学生其学号是连续编号的,由此设计出一个即公平(每个班最多选1人)又便利(不用分班)的最强队伍选择方法。
输入格式:
输入两行数据,第一行给出两个正整数N和K,表示学生总人数和班级人数上限,满足2K<N≤105 (至少有三个班)。接下来一行给出N个正整数,用空格分开,依次表示从学号0
到学号N-1
的学生成绩。末尾的成绩后面没有空格。所有成绩值都在区间[1,105]以内。
输出格式:
输出两行数据。第一行给出选出的最强队伍的总成绩;第二行给出组队的三名学生的学号a b c,满足 b−a≥K∧c−b≥K。数值间用空格分开,末尾不留空格。 如果最强队伍有多组,输出学号序列字典序最小的队伍。
输入样例1:
10 3
6 2 7 8 9 2 8 5 7 1
输出样例1:
22
0 3 6
注:学号0+学号4+学号8也是最强队伍,但字典序较大。
输入样例2:
6 2
1 2 3 4 5 6
输出样例2:
12
1 3 5
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
代码
#include <iostream>
using namespace std;
#include <queue>
#include <vector>
void clear(int*a,int size)
{
for(int i=0;i<size;i++)
{
a[i]=0;
}
}
int main()
{
//输入两行数据,第一行给出两个正整数N和K,表示学生总人数和班级人数上限,满足2K<N≤10^5(至少有三个班)。
int N,K;//学生总人数N+班级人数上限K
cin>>N>>K;
int score[100000]={0};//储存全部同学的初始成绩
//接下来一行给出N个正整数,用空格分开,依次表示从学号0到学号N-1的学生成绩。末尾的成绩后面没有空格。所有成绩值都在区间[1,10^5]以内。
//输出两行数据。第一行给出选出的最强队伍的总成绩;第二行给出组队的三名学生的学号a b c,满足 b−a≥K∧c−b≥K。数值间用空格分开,末尾不留空格。
//如果最强队伍有多组,输出学号序列字典序最小的队伍。
//a的值在0到(N-1)-2*K之间
//b的值在a+K到(N-1)-K之间
//c的值在b+K到N-1之间
int maxScore1[N];//到目前为止的第一个最大数
int maxScore2[N];//到目前为止的第二个和第一个的最大数
int maxScore3[N];//到目前为止的三个数的和的最大数
int index1[N];//第一个最大数的最先位置
int index2[N];//第二个和最大数的最先的位置
int index3[N];//第三个三数之和最大值最先的位置
//清零
clear(maxScore1,N);
clear(maxScore2,N);
clear(maxScore3,N);
clear(index1,N);
clear(index2,N);
clear(index3,N);
cin>>score[0];
//开始操作
maxScore1[0]=score[0];
index1[0]=0;
for(int i=1;i<=N-1;i++)
{
cin>>score[i];//原值
if(score[i]>maxScore1[i-1])
{
maxScore1[i]=score[i];
index1[i]=i;
}
else
{
maxScore1[i]=maxScore1[i-1];
index1[i]=index1[i-1];
}
}
maxScore2[K]=score[K]+maxScore1[0];
index2[K]=K;
for(int i=K+1;i<=N-1;i++)
{
if(maxScore1[i-K]+score[i]>maxScore2[i-1])
{
maxScore2[i]=maxScore1[i-K]+score[i];
index2[i]=i;
}
else
{
maxScore2[i]=maxScore2[i-1];
index2[i]=index2[i-1];
}
}
maxScore3[2*K]=score[2*K]+maxScore2[K];
index3[2*K]=2*K;
for(int i=2*K+1;i<=N-1;i++)
{
if(maxScore2[i-K]+score[i]>maxScore3[i-1])
{
maxScore3[i]=maxScore2[i-K]+score[i];
index3[i]=i;
}
else
{
maxScore3[i]=maxScore3[i-1];
index3[i]=index3[i-1];
}
}
cout<<maxScore3[N-1]<<endl;
int c=index3[N-1];
int b=index2[c-K];
int a=index1[b-K];
cout<<a<<" "<<b<<" "<<c;
return 0;
}