题目描述
有 n 个人在一个水龙头前排队接水,假如每个人接水的时间为 Ti,请编程找出这 n 个人排队的一种顺序,使得 n 个人的平均等待时间最小。
输入格式
第一行为一个整数 n。
第二行 n 个整数,第 i 个整数 Ti 表示第 i 个人的接水时间 Ti。
输出格式
输出文件有两行,第一行为一种平均时间最短的排队顺序;第二行为这种排列方案下的平均等待时间(输出结果精确到小数点后两位)。
输入输出样例
输入
10
56 12 1 99 1000 234 33 55 99 812
输出
3 2 7 8 1 4 9 6 10 5
291.90
说明/提示
1≤n≤1000,1≤ti≤106,不保证 ti 不重复。
代码
无注释版
#include<bits/stdc++.h>
const int N=1e6+10;
using namespace std;
struct p{
int h;
int t;
}a[N];
bool cmp(p x,p y){
return x.t<y.t;
}
double s;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].t;
a[i].h=i;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++){
printf("%d ",a[i].h);
s+=a[i].t*(n-i);
}
cout<<"\n";
double r=s/n;
printf("%.2f",r);
}
有注释版
#include<bits/stdc++.h> // 包含常用头文件
const int N=1e6+10; // 定义常量N,表示最大可能的接水人数
using namespace std;
// 定义结构体p,存储每个人的编号h和接水时间t
struct p{
int h; // 人的编号
int t; // 接水时间
}a[N]; // 声明结构体数组a,最多可存储1e6+10个人
// 自定义比较函数,按接水时间t从小到大排序
bool cmp(p x, p y){
return x.t < y.t;
}
double s; // 总等待时间
int main(){
int n; // 人数
cin >> n; // 输入人数n
for(int i = 1; i <= n; i++){
cin >> a[i].t; // 输入第i个人的接水时间
a[i].h = i; // 记录第i个人的编号
}
// 按接水时间从小到大排序
sort(a + 1, a + n + 1, cmp);
// 输出最优排队顺序(接水时间短的优先)
for(int i = 1; i <= n; i++){
printf("%d ", a[i].h); // 输出编号
// 计算总等待时间:当前人的接水时间 * 剩余人数(包括自己)
s += a[i].t * (n - i);
}
cout << "\n"; // 换行
// 计算平均等待时间 = 总等待时间 / 人数
double r = s / n;
printf("%.2f", r); // 输出结果,保留两位小数
return 0;
}