#include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

class Data
{
public:
    long long time;
    int id;
    int kind; // 0 : 客の来店
              // 1 : 待ち時間が長く帰宅
              // 2 : 食事を終えて帰宅
              // 3 : 閉店
    Data(long long time0, int id0, int kind0){
        time = time0;
        id = id0;
        kind = kind0;
    }
    bool operator< (const Data& d) const{
        return make_pair(time, kind) < make_pair(d.time, d.kind);
    }
};

pair<int, int> findCounter(const vector<vector<bool> >& used, int num)
{
    int n = used.size();

    int sl = -1;
    int sr = -1;
    pair<int, int> ret(-1, -1);
    for(int i=0; i<n; ++i){
        int m = used[i].size();
        int size = 0;
        for(int j=0; j<m; ++j){
            if(used[i][j]){
                size = 0;
                continue;
            }

            ++ size;
            if(size >= num){
                int sl2;
                int sr2;
                int k;
                if(j+1 == size && j == m-1){
                    sl2 = sr2 = INT_MAX;
                    k = 0;
                }else if(j+1 == size){
                    sl2 = INT_MAX;
                    sr2 = size - num;
                    k = 0;
                }else if(j == m-1){
                    sl2 = size - num;
                    sr2 = INT_MAX;
                    k = j - num + 1;
                }else{
                    sl2 = (size - num) / 2;
                    sr2 = (size - num + 1) / 2;
                    k = j - size + (size - num) / 2 + 1;
                }
                if(min(sl2, sr2) > min(sl, sr) || (min(sl2, sr2) == min(sl, sr) && max(sl2, sr2) > max(sl, sr))){
                    sl = sl2;
                    sr = sr2;
                    ret = make_pair(i, k);
                }
            }
        }
    }

    return ret;
}

int main()
{
    for(;;){
        int n, m, closeTime; // カウンター数、グループ数、閉店時間
        cin >> n >> m >> closeTime;
        if(n == 0)
            return 0;

        vector<int> counter(n); // 各カウンターの席の数
        for(int i=0; i<n; ++i)
            cin >> counter[i];
        vector<vector<bool> > used(n); // 使用中のカウンターの席
        for(int i=0; i<n; ++i)
            used[i].assign(counter[i], false);

        vector<int> come(m), num(m), wait(m), eat(m); // 来店時間、各グループの客の人数、最大待ち時間、食事時間
        for(int i=0; i<m; ++i)
            cin >> come[i] >> num[i] >> wait[i] >> eat[i];

        multiset<Data> ms;
        ms.insert(Data(closeTime, -1, 3));
        for(int i=0; i<m; ++i){
            ms.insert(Data(come[i], i, 0));
            ms.insert(Data(come[i] + wait[i], i, 1));
        }

        queue<int> q;                         // 待っているグループ
        vector<pair<int, int> > sit(m);       // 各グループが使っているカウンターの位置
        vector<double> satisfaction(m, -1.0); // 各グループの満足度
        bool isClose = false;                 // 閉店時間を過ぎたかどうか
        while(!ms.empty()){
            long long time = ms.begin()->time;
            while(!ms.empty() && ms.begin()->time == time){
                Data d = *ms.begin();
                ms.erase(ms.begin());

                if(d.kind == 0){
                    q.push(d.id);
                }else if(d.kind == 2){
                    for(int i=0; i<num[d.id]; ++i)
                        used[sit[d.id].first][sit[d.id].second + i] = false;
                }else if(d.kind == 3){
                    isClose = true;
                }
            }
            if(isClose)
                break;

            while(!q.empty()){
                int id = q.front();
                if(time > come[id] + wait[id]){
                    q.pop();
                    continue;
                }

                pair<int, int> pos = findCounter(used, num[id]);
                if(pos.first == -1){
                    if(time == come[id] + wait[id]){
                        q.pop();
                        continue;
                    }
                    break;
                }

                q.pop();
                for(int i=0; i<num[id]; ++i)
                    used[pos.first][pos.second + i] = true;
                sit[id] = pos;
                satisfaction[id] = (wait[id] - (time - come[id])) / (double)wait[id];
                ms.insert(Data(time + eat[id], id, 2));
            }
        }

        double ret = 0.0;
        for(int i=0; i<m; ++i)
            ret += satisfaction[i] * num[i];
        ret /= accumulate(num.begin(), num.end(), 0);
        printf("%.10f\n", ret);
    }
}

Measured memory_bytes: 2784