#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
#include <fstream>
#include <map>
using namespace std;
struct STUDENT {
string name;
double p1, p2, avg;
vector<int> options;
};
STUDENT getInfor (string str) {
STUDENT a;
vector <int> commaPos;
for (int i = 0; i < str.length(); i++) {
if (str[i] == ',') commaPos.push_back(i);
}
commaPos.push_back(str.length());
int i = 0;
a.name = str.substr(1, commaPos[i] - 2);
a.p1 = stod(str.substr(commaPos[i] + 1, commaPos[i + 1] - commaPos[i] - 1));
i++;
a.p2 = stod(str.substr(commaPos[i] + 1, commaPos[i + 1] - commaPos[i] - 1));
i++;
a.avg = (a.p1 + a.p2) / 2;
while (commaPos[i] != str.length()) {
(a.options).push_back(stoi(str.substr(commaPos[i] + 1, commaPos[i + 1] - commaPos[i] - 1)));
i++;
}
return a;
}
bool higher (STUDENT a, STUDENT b) {
if (a.avg > b.avg) return true;
if (a.avg == b.avg) {
if (a.p1 > b.p1) return true;
else if (a.p1 == b.p1) {
if (a.p2 > b.p2) return true;
}
}
return false;
}
bool lower (STUDENT a, STUDENT b) {
if (a.avg < b.avg) return true;
if (a.avg == b.avg) {
if (a.p1 < b.p1) return true;
else if (a.p1 == b.p1) {
if (a.p2 < b.p2) return true;
}
}
return false;
}
int partition (vector<STUDENT>& a, int l, int r) {
STUDENT p = a[l];
int i = l, j = r + 1;
while (true) {
do i++; while (higher(a[i], p) && i <= r);
do j--; while (lower(a[j], p));
if (i >= j) break;
swap(a[i], a[j]);
}
swap(a[l], a[j]);
return j;
}
void quickSort (vector<STUDENT>& a, int l, int r) {
if (l < r) {
int s = partition(a, l, r);
quickSort(a, l, s - 1);
quickSort(a, s + 1, r);
}
}
void getList (vector<vector<STUDENT> >& finalList, vector<STUDENT> listOfStudents, vector<int> slots) {
for (auto x : listOfStudents) {
bool ac = false;
for (auto op : x.options) {
if (finalList[op].size() < slots[op] || ((finalList[op].back()).avg == x.avg && (finalList[op].back()).p1 == x.p1 && (finalList[op].back()).p2 == x.p2)) {
ac = true;
finalList[op].push_back(x);
break;
}
}
if (ac == false) {
finalList[0].push_back(x);
}
}
}
int main () {
int m;
cout << "Enter m: ";
cin >> m;
cout << "Pairs option maximum number of admitted candidates, separated by blanks: " << endl;
vector<int> slots(m + 1);
for (int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
slots[a] = b;
}
cin.ignore();
cout << "Note: Ctrl + D on Mac/ Linux or Ctrl + Z on Windows to stop." << endl;
vector<STUDENT> listOfStudents;
string data;
while(getline(cin, data)) {
STUDENT tmp = getInfor(data);
listOfStudents.push_back(tmp);
}
vector<vector<STUDENT>> listByOptions(m+1);
quickSort(listOfStudents, 0, listOfStudents.size() - 1);
getList(listByOptions, listOfStudents, slots);
for (int i = 1; i <= m; i++) {
if (listByOptions[i].size() != 0) {
cout << "Successful candidates for option " << i << endl;
}
for (int j = 0; j < listByOptions[i].size(); j++) {
cout << j + 1 << ". " << listByOptions[i][j].name << " " << fixed << setprecision(2) << listByOptions[i][j].avg << endl;
}
}
if (listByOptions[0].size() != 0) {
cout << "Unsuccessful candidates" << endl;
for (int j = 0; j < listByOptions[0].size(); j++) {
cout << j + 1 << ". " << listByOptions[0][j].name << " " << fixed << setprecision(2) << listByOptions[0][j].avg << endl;
}
}
}