// by Dan Joyce
// solves Problem 5: Making the Grade 
// of 1996 Mid Atlantic programming contest

// input is info about student grades 
// output is class gpas 

import java.io.*;
import common.doinput;

class problem5 {

  public static void main (String [] args) throws IOException {

    int n, s, t;                         // number of classes, students, tests
    int tgrades [][] = new int [32][12]; // tgrades
    int bonus [] = new int [32];         // bonus points
    int absents [] = new int [32];       // absences
    float averages [] = new float [32];  // averages
    int grades [] = new int [32];        // grades
    int lowest, sum;                     // for average calculation
    float fsum, classavg, classSD;       // float sum, class average and SD
    float avgGradePts;                   // average grade points
    int i, j, k;                         // loop control

    doinput myinput = new doinput();

    System.out.println ("MAKING THE GRADE OUTPUT");

    // get count of classes 
    n = myinput.nextint();

  for (k=1; k <= n; k++)
    {
    // get inout
    s = myinput.nextint();
    t = myinput.nextint();
    for (i = 1; i <= s; i++)
      { for (j = 1; j <= t; j++)
          { 
           tgrades[i][j] = myinput.nextint();
          };
        bonus[i] = myinput.nextint();
        absents[i] = myinput.nextint();
      };

    // calculate averages
    if (t > 2)   // drop lowest grade
      { for (i=1; i <= s; i++)
          { lowest = 100;  sum = 0;
            for (j=1; j <= t; j++)
              { if (tgrades[i][j] < lowest) lowest = tgrades[i][j];
                sum = sum + tgrades[i][j]; 
              };
            averages[i] = ((float)(sum - lowest)) / ((float)(t-1));
          };
      }
    else        // do not drop lowest grade
      { for (i=1; i <= s; i++)
          { sum = 0;
            for (j=1; j <= t; j++)
              sum = sum + tgrades[i][j];
            averages[i] = (float) sum / (float) t;
            averages[i] = (float) ( (float) (Math.round(averages[i] * 10)) 
                          / 10.0 );
          };
      };

    // calculate class average
    fsum = 0;
    for (i=1; i <= s; i++)
      fsum = fsum + averages[i];
    classavg = (fsum / (float) s);
    classavg = (float)( (float) (Math.round(classavg * 10)) / 10.0 );

    // calculate class standard deviation
    fsum = 0;
    for (i=1; i <= s; i++)
      fsum = fsum + ((classavg-averages[i])*(classavg-averages[i]));
    fsum = fsum/s;
    classSD = (float) Math.sqrt(fsum);
    classSD = (float) ( (float) (Math.round(classSD * 10)) / 10.0 );
    if (classSD < 1.0) classSD = (float) 1.0;

    // add bonus points into student averages
    for (i=1; i <= s; i++)
      averages[i] = averages[i] + ((bonus[i] / 2 ) * 3);

    // determine unadjusted grades
    for (i=1; i <= s; i++)
      { if (averages[i] >= (classavg + classSD) ) grades[i] = 4;
        else if (averages[i] >= (classavg) )      grades[i] = 3;
        else if (averages[i] >= (classavg - classSD) ) grades[i] = 2;
        else grades[i] = 1;
      }

    // adjust grades for absences
    for (i=1; i <= s; i++)
      { grades[i] = grades[i] - (absents[i] / 4);
        if (grades[i] < 0) grades[i] = 0;
      };

    // adjust for perfect attendance
    for (i=1; i <= s; i++)
        if ( ( grades[i] != 4 ) && (absents[i] == 0))
           grades[i] = grades[i] + 1;

    // calculate average grade points
    sum = 0;
    for (i=1; i <= s; i++)
       sum = sum + grades[i];
    avgGradePts = (float) sum  / (float) s;
    avgGradePts = (float)( (float) (Math.round(avgGradePts * 10)) / 10.0 );

    System.out.println (avgGradePts); 
    }  // end of the for k loop

    System.out.println ("END OF OUTPUT");
  }
}

