Statistical problem (statistic)
Description
Betty is working on a large-scale data statistics problem. She has obtained \(n\) positive integers \(a_i\). Now she wants to select \(n_1\) and \(n_2\) numbers, so that the average of \(n_1\) numbers minus the average of \(n_2\) numbers maximum. Programming helped her complete this problem.
Format
Input
The first row is positive integers \(n\), \(n_1\), and \(n_2\) (\(n≤3 \times 10^6\), \(n_1\), \(n_2≤20\), \(n_1+n_2≤n\)); the second row is \(n\) positive integers \(a_i\) (\(≤10^9\)) separated by spaces.
Output
Only one real number represents the result, and 3 decimal places are reserved.
Sample
Input
2 1 1
1 5
Output
4.000
Hint
\(30\%\) data, guarantee \(n≤10^4\);
\(60\%\) data, guarantee \(n≤10^6\);
\(100\%\) data, guarantee \(n≤3 \times 10^6\).
Sample Code
#include <cstdio>
#include <algorithm>
#include <functional>
#include <queue>
//#include <vector>
using namespace std;
const int N=3000005;////
void in(int &x){
char c=getchar();
while (c<'0' || c>'9') c=getchar();
for (x=0; c>='0' && c<='9'; c=getchar())
x=x*10+c-'0';
}
int a[N];
int main(){
freopen("statistic.in", "r", stdin);
freopen("statistic.out", "w", stdout);
int n, n1, n2;
scanf("%d %d %d", &n, &n1, &n2);
//方法1:直接调用sort,时间较慢
/*for (int i=0; i<n; i++)
in(a[i]);
sort(a, a+n);
double s1=0.0, s2=0.0;
for (int i=0; i<n2; i++)
s2+=a[i];
for (int i=n-n1; i<n; i++)
s1+=a[i];
printf("%.3f\n", s1/n1-s2/n2);*/
//方法2:使用nth_element
/*double s1=0.0, s2=0.0;
for (int i=0; i<n; i++)
in(a[i]);
nth_element(a, a+n1, a+n, greater<int>());
for (int i=0; i<n1; i++)
s1+=a[i];
nth_element(a, a+n2, a+n);
for (int i=0; i<n2; i++)
s2+=a[i];
printf("%.3f\n", s1/n1-s2/n2);
*/
//方法3:调用partial_sort
/*for (int i=0; i<n; i++)
in(a[i]);
double s1=0, s2=0;
partial_sort(a, a+n2, a+n);
for (int i=0; i<n2; i++)
s2+=a[i];
partial_sort(a, a+n1, a+n, greater<int>()); //greater函数需头文件<functional>
for (int i=0; i<n1; i++)
s1+=a[i];
printf("%.3f\n", s1/n1-s2/n2); */
/*//方法4:冒泡
int x, mx[21], mn[21];
for (int i=0; i<=n1; i++)
mx[i]=-1;
for (int i=0; i<=n2; i++)
mn[i]=1<<30;
for (int i=0; i<n; i++){
in(x);//scanf("%d", &x);
for (int j=n1-1; j>=0; j--)
if (x>mx[j]) {
mx[j+1]=mx[j]; mx[j]=x;
}
else break;
for (int j=n2-1; j>=0; j--)
if (x<mn[j]) {
mn[j+1]=mn[j]; mn[j]=x;
}
else break;
}
double s1=0.0, s2=0.0;
for (int i=0; i<n1; i++)
s1+=mx[i];
for (int i=0; i<n2; i++)
s2+=mn[i];
printf("%.3f\n", s1/n1-s2/n2); */
//方法5:优先队列
int x;
priority_queue <int, vector<int>, greater<int> > ux;
priority_queue <int> vx;
for (int i=0; i<n1; i++)
ux.push(-1);
for (int i=0; i<n2; i++)
vx.push(1<<30);
for (int i=0; i<n; i++){
in(x);
ux.push(x); ux.pop();
vx.push(x); vx.pop();
}
double s1=0.0, s2=0.0;
for (int i=0; i<n1; i++) {
s1+=ux.top(); ux.pop();
}
for (int i=0; i<n2; i++) {
s2+=vx.top(); vx.pop();
}
printf("%.3f\n", s1/n1-s2/n2); /**/
return 0;
}