洛谷题单【算法1-5】贪心——P1223 排队接水

188 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第17天,点击查看活动详情

P1223 排队接水

题目描述

nn 个人在一个水龙头前排队接水,假如每个人接水的时间为 TiT_i,请编程找出这 nn 个人排队的一种顺序,使得 nn 个人的平均等待时间最小。

输入格式

第一行为一个整数 nn

第二行 nn 个整数,第 ii 个整数 TiT_i 表示第 ii 个人的等待时间 TiT_i

输出格式

输出文件有两行,第一行为一种平均时间最短的排队顺序;第二行为这种排列方案下的平均等待时间(输出结果精确到小数点后两位)。

样例 #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

提示

n1000,ti106n \leq 1000,t_i \leq 10^6,不保证 tit_i 不重复。

tit_i 重复时,按照输入顺序即可(sort 是可以的)

思路

还是结构体+排序,主要是要储存每个人的序号和打水时间以及等待的时间

然后对于打水时间进行排序,打水打的快的人先打

这样会让等待的人数迅速减少,进而减少人群的平均等待时间

代码

// P1223 排队接水
// 贪心,结构体排序
#include <bits/stdc++.h>
using namespace std;

struct p{
    int uid;
    int t;
    int wait;
}pp[1010];

bool cmp(p a, p b){
    return a.t < b.t; 
}

int main(){
    int n;
    double avewait = 0;//坑爹啊,这题要用双精度
    cin >> n;

    // 读取数据
    for(int i=0; i<n; i++){
        pp[i].uid = i+1;
        cin >> pp[i].t;
        pp[i].wait = 0;
    }
    // 对数据依据打水时间排序
    sort(pp, pp+n, cmp);
    // 计算等待时间
    for(int i=0; i<n; i++){
        for(int j=0; j<i; j++){
            pp[i].wait += pp[j].t;
        }
        avewait += pp[i].wait;
    }
    // 计算平均等待时间
    avewait = avewait*1.0/n*1.0;
    for(int i=0; i<n-1; i++){
        cout << pp[i].uid << " ";
    }
    cout << pp[n-1].uid << endl;
    printf("%.2f",avewait);
}