题目描述
有 n n n 个人在一个水龙头前排队接水,假如每个人接水的时间为 T i T_i Ti,请编程找出这 n n n 个人排队的一种顺序,使得 n n n 个人的平均等待时间最小。
输入格式
第一行为一个整数 n n n。
第二行 n n n 个整数,第 i i i 个整数 T i T_i Ti 表示第 i i i 个人的等待时间 T i T_i Ti。
输出格式
输出文件有两行,第一行为一种平均时间最短的排队顺序;第二行为这种排列方案下的平均等待时间(输出结果精确到小数点后两位)。
样例 #1
样例输入 #1
10
56 12 1 99 1000 234 33 55 99 812
样例输出 #1
3 2 7 8 1 4 9 6 10 5
291.90
提示
n ≤ 1000 , t i ≤ 1 0 6 n \leq 1000,t_i \leq 10^6 n≤1000,ti≤106,不保证 t i t_i ti 不重复。
当 t i t_i ti 重复时,按照输入顺序即可(sort 是可以的)
解题思路:
emmm很典型的一道题,解题思路就是让T较小的排在前面
因为排在最前面的人,所有人都要等他,对等待时间影响较大
实现代码如下:
#include <iostream>
#include <algorithm>
#include <vector>
#include <iomanip>
using namespace std;
class person {
public:
int id;
int t;
bool operator>(const person p) const {
return t > p.t;
}
bool operator<(const person p) const {
return t < p.t;
}
};
vector<person> person_queue;
int main() {
int n;
double sum_t = 0.0;
person temp_p;
cin >> n;
for (int i = 1; i <= n; i++) {//读入数据
cin >> temp_p.t;
temp_p.id = i;
person_queue.push_back(temp_p);
}
sort(person_queue.begin(), person_queue.end());//排序
int head = 0, tail = int(person_queue.size());
while (head != tail) {//输出顺序,统计sum_t
cout << person_queue[head].id;
if (head != tail - 1) putchar(' ');
sum_t += (tail - head - 1) * person_queue[head].t;
head++;
}
cout << '\n' << setiosflags(ios::fixed) << setprecision(2) << sum_t / n;//输出平均时间
return 0;
}
这里解释一下为什么不用priority_queue而用vector + sort(),因为前者不能“当 t i t_i ti重复时,按照输入顺序输出“