题目描述
有n个人在一个水龙头前排队接水,假如每个人接水的时间为Ti,请编程找出这n个人排队的一种顺序,使得n个人的平均等待时间最小。
输入输出格式
输入格式:
输入文件共两行,第一行为n;第二行分别表示第1个人到第n个人每人的接水时间T1,T2,…,Tn,每个数据之间有1个空格。
输出格式:
输出文件有两行,第一行为一种排队顺序,即1到n的一种排列;第二行为这种排列方案下的平均等待时间(输出结果精确到小数点后两位)。
输入输出样例
说明
n<=1000
ti<=1e6,不保证ti不重复
当ti重复时,按照输入顺序即可(sort是可以的)
//手写
#include<bits/stdc++.h> using namespace std; int main() { double ans=0; int n,a[100000],b[100000]={0},c[100000]={0}; cin>>n; for(int i=1;i<=n;i++) cin>>a[i],b[i]=a[i]; sort(a+1,a+1+n); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++){ if(a[i]==b[j]) b[j]=-100,cout<<j<<" "; } ans+=a[i-1]; a[i]+=a[i-1]; } printf("\n%.2lf",ans/n); }
//下面是比较高端的操作
1.pair数组
当有两个元素需要绑定在一起的时候可以用结构体 , 此时也可以用 pair 数组去替代结构体 。
http://www.cnblogs.com/ccut-ry/p/7606787.html
#include<bits/stdc++.h> using namespace std; int main() { int n; double sum= 0.0f; pair<int ,int>a[1008]; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i].first),a[i].second=i+1; sort(a,a+n); for(int i=0;i<n;i++) { sum+=a[i].first*(n-i-1); printf("%d ",a[i].second); } printf("\n%.2lf",sum/n); return 0; }
2.结构体
#include<bits/stdc++.h> using namespace std; struct water{ int time,num; }p[1008]; bool comp(water a,water b) { if(a.time!=b.time) return a.time<b.time; return a.num<b.num; } int n; double sum; int main() { scanf("%d",&n); for(int i=1; i<=n; i++) { //输入时间并重置序号 scanf("%d",&p[i].time); p[i].num=i; } sort(p+1,p+n+1,comp); for(int i=1;i<=n;i++) { printf("%d ",p[i].num); sum+=i*p[n-i].time; } sum/=n; printf("\n%.2f",sum); return 0; }
3.循环
#include<bits/stdc++.h> #define for(a,c,e) for(int a=c;a<=e;a++) #include<iomanip> using namespace std; int main() { int n,a[1002]; double sum; scanf("%d",&n); for(i,1,n) scanf("%d",&a[i]); for(i,1,n) { long long m1=0,m2=9000000; for(j,1,n) if(a[j]<m2)m1=j,m2=a[j]; printf("%d ",m1); a[m1]=9999999; sum+=m2*(n-i); } //printf("\n%.2f",sum/n); cout<<endl<<fixed<<setprecision(2)<<sum/n; return 0; }