题一:P1223 排队接水
排队接水
题目描述
有 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
提示
1 ≤ n ≤ 1000 1\le n \leq 1000 1≤n≤1000, 1 ≤ t i ≤ 1 0 6 1\le t_i \leq 10^6 1≤ti≤106,不保证 t i t_i ti 不重复。
方法一:结构体+前缀和
代码
#include<bits/stdc++.h>
using namespace std;
struct Time{
int num; //打水编号
int t; //打水时间
};
int main()
{
Time time[100010];
int qianzui[100010]; //前缀和数组
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>time[i].t;
time[i].num=i;
}
//结构体排序
sort(time+1,time+n+1,[](Time a, Time b){return a.t < b.t;});
qianzui[1]=time[1].t;
double sum=qianzui[1],ave=0;
for(int i=2;i<=n-1;i++)
{
qianzui[i]=time[i].t+qianzui[i-1]; //计算每个人的等待时间
sum+=qianzui[i];
}
ave=sum/n;//平均等待时间
for(int i=1;i<=n;i++)
{
cout<<time[i].num<<" ";
}
printf("\n%.2lf",ave);
return 0;
}
方法二:C++STL
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
pair<int,int>time[n]; //C++pair
//我们可以用first访问pair第一个值,second访问pair第二个值
for(int i=1;i<=n;i++)
{
cin>>time[i].first; //这里的first代表接水时间
time[i].second=i; //second表示接水人的b编号
}
sort(time+1,time+n+1); //排序
double sum=0.0f;
for(int i=1;i<=n;i++)
{
sum+=time[i].first*(n-i)<<' '; //计算平均等待时间
cout<<time[i].second;
}
printf("\n%.2lf",sum/n);
return 0;
}
总结
这是一道贪心算法基础题,通过把接水时间短的排在最前面,减少后面人的 等待时间,从而减少平均等待时间。
本文章为平时做题笔记,有什么技术性问题都可以在评论区打出来,我都会认真查看并尽力解答大家的疑问。欢迎大佬来提出修改意见,感谢大家的关注和支持!