fork download
  1. #include <iostream>
  2. #include <map>
  3. #include <vector>
  4. #include <string>
  5. #include <algorithm>
  6. #include <sstream>
  7. #include <iomanip>
  8. #include <climits>
  9.  
  10. using namespace std;
  11.  
  12. // Helper function: Convert time in "hh:mmAM/PM" to minutes since midnight
  13. int convertTimeToMinutes(const string& time) {
  14. int hours = stoi(time.substr(0, time.find(':')));
  15. int minutes = stoi(time.substr(time.find(':') + 1, 2));
  16. string ampm = time.substr(time.size() - 2);
  17. if (ampm == "PM" && hours != 12) hours += 12;
  18. if (ampm == "AM" && hours == 12) hours = 0;
  19. return hours * 60 + minutes;
  20. }
  21.  
  22. // Function to process logs and organize entries and exits
  23. map<int, map<int, pair<vector<int>, vector<int>>>> processLogs(
  24. const vector<tuple<int, string, string, string>>& logs) {
  25.  
  26. map<int, map<int, pair<vector<int>, vector<int>>>> employeeLogs;
  27.  
  28. for (const auto& [employeeID, action, location, time] : logs) {
  29. // Filter only logs with "room" in the location
  30. if (location.find("room") == string::npos) continue;
  31.  
  32. int roomNumber = stoi(location.substr(4)); // Extract room number
  33. int timeInMinutes = convertTimeToMinutes(time);
  34.  
  35. if (action == "enters") {
  36. employeeLogs[employeeID][roomNumber].first.push_back(timeInMinutes);
  37. } else if (action == "exits") {
  38. employeeLogs[employeeID][roomNumber].second.push_back(timeInMinutes);
  39. }
  40. }
  41.  
  42. // Sort entries and exits for every room
  43. for (auto& [employeeID, rooms] : employeeLogs) {
  44. for (auto& [roomNumber, logs] : rooms) {
  45. sort(logs.first.begin(), logs.first.end()); // Sort entries
  46. sort(logs.second.begin(), logs.second.end()); // Sort exits
  47. }
  48. }
  49.  
  50. return employeeLogs;
  51. }
  52.  
  53. // Function to calculate work done and consistency
  54. pair<int, bool> calculateWorkDoneAndConsistency(
  55. const map<int, map<int, pair<vector<int>, vector<int>>>>& employeeLogs,
  56. map<int, map<int, int>>& workDonePerRoom, int employeeID) {
  57.  
  58. int totalWorkDone = 0;
  59. bool isInconsistent = false;
  60.  
  61. for (const auto& [roomNumber, logs] : employeeLogs.at(employeeID)) {
  62. const auto& entries = logs.first;
  63. const auto& exits = logs.second;
  64.  
  65. vector<bool> entryUsed(entries.size(), false);
  66. vector<bool> exitUsed(exits.size(), false);
  67.  
  68. int roomWorkDone = 0;
  69.  
  70. // Map exits to the nearest prior entry
  71. for (size_t j = 0; j < exits.size(); ++j) {
  72. for (size_t i = 0; i < entries.size(); ++i) {
  73. if (!entryUsed[i] && entries[i] < exits[j]) {
  74. roomWorkDone += exits[j] - entries[i];
  75. entryUsed[i] = true;
  76. exitUsed[j] = true;
  77. break;
  78. }
  79. }
  80. }
  81.  
  82. // Check if unmatched entries or exits remain
  83. if (any_of(entryUsed.begin(), entryUsed.end(), [](bool used) { return !used; }) ||
  84. any_of(exitUsed.begin(), exitUsed.end(), [](bool used) { return !used; })) {
  85. isInconsistent = true;
  86. }
  87.  
  88. totalWorkDone += roomWorkDone;
  89. workDonePerRoom[employeeID][roomNumber] = roomWorkDone;
  90. }
  91.  
  92. return {totalWorkDone, isInconsistent};
  93. }
  94.  
  95. // Main function
  96. int main() {
  97. int n;
  98. cin >> n;
  99.  
  100. vector<tuple<int, string, string, string>> logs(n);
  101. for (int i = 0; i < n; ++i) {
  102. int employeeID;
  103. string action, location, time;
  104. cin >> employeeID >> action >> location >> time;
  105. logs[i] = {employeeID, action, location, time};
  106. }
  107.  
  108. int suspectID;
  109. cin >> suspectID;
  110.  
  111. // Step 1: Sort logs and organize data
  112. sort(logs.begin(), logs.end(), [](const auto& a, const auto& b) {
  113. if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);
  114. return get<2>(a) < get<2>(b);
  115. });
  116. auto employeeLogs = processLogs(logs);
  117.  
  118. // Step 2: Calculate work done and consistency for each employee
  119. map<int, map<int, int>> workDonePerRoom;
  120. map<int, pair<int, bool>> results; // {EmployeeID: {TotalWorkDone, IsInconsistent}}
  121.  
  122. for (const auto& [employeeID, _] : employeeLogs) {
  123. results[employeeID] = calculateWorkDoneAndConsistency(employeeLogs, workDonePerRoom, employeeID);
  124. }
  125.  
  126. // Step 3: Print individual employee status
  127. cout << "Employee Status:\n";
  128. for (const auto& [employeeID, result] : results) {
  129. const auto& [totalWorkDone, isInconsistent] = result;
  130. cout << "Employee ID: " << employeeID << "\n";
  131. cout << " Consistency: " << (isInconsistent ? "Inconsistent" : "Consistent") << "\n";
  132. cout << " Total Work Done: " << totalWorkDone << " minutes\n";
  133. cout << " Work Done by Room:\n";
  134. for (const auto& [room, work] : workDonePerRoom[employeeID]) {
  135. cout << " room" << room << ": " << work << " minutes\n";
  136. }
  137. cout << "\n";
  138. }
  139.  
  140. // Step 4: Determine result for suspect
  141. bool suspectInconsistent = results[suspectID].second;
  142. int suspectWork = results[suspectID].first;
  143. int leastWork = INT_MAX;
  144. bool otherInconsistentWithLessWork = false;
  145.  
  146. for (const auto& [employeeID, result] : results) {
  147. const auto& [workDone, isInconsistent] = result;
  148. if (workDone < leastWork) leastWork = workDone;
  149. if (employeeID != suspectID && isInconsistent && workDone < suspectWork) {
  150. otherInconsistentWithLessWork = true;
  151. }
  152. }
  153.  
  154. if (suspectInconsistent || otherInconsistentWithLessWork) {
  155. cout << "Cannot be determined\n";
  156. } else if (suspectWork == leastWork) {
  157. cout << "Yes\n";
  158. } else {
  159. cout << "No\n";
  160. }
  161.  
  162. return 0;
  163. }
  164.  
Success #stdin #stdout 0.03s 25804KB
stdin
8
103 enters room3 10:00AM
102 exits room2 09:50AM
101 enters room1 09:00AM
103 exits room3 10:20AM
102 enters room2 09:30AM
101 exits room1 09:15AM
102 enters room2 09:40AM
102 exits room2 09:45AM
101
stdout
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include <climits>

using namespace std;

// Helper function: Convert time in "hh:mmAM/PM" to minutes since midnight
int convertTimeToMinutes(const string& time) {
    int hours = stoi(time.substr(0, time.find(':')));
    int minutes = stoi(time.substr(time.find(':') + 1, 2));
    string ampm = time.substr(time.size() - 2);
    if (ampm == "PM" && hours != 12) hours += 12;
    if (ampm == "AM" && hours == 12) hours = 0;
    return hours * 60 + minutes;
}

// Function to process logs and organize entries and exits
map<int, map<int, pair<vector<int>, vector<int>>>> processLogs(
    const vector<tuple<int, string, string, string>>& logs) {
    
    map<int, map<int, pair<vector<int>, vector<int>>>> employeeLogs;

    for (const auto& [employeeID, action, location, time] : logs) {
        // Filter only logs with "room" in the location
        if (location.find("room") == string::npos) continue;

        int roomNumber = stoi(location.substr(4)); // Extract room number
        int timeInMinutes = convertTimeToMinutes(time);

        if (action == "enters") {
            employeeLogs[employeeID][roomNumber].first.push_back(timeInMinutes);
        } else if (action == "exits") {
            employeeLogs[employeeID][roomNumber].second.push_back(timeInMinutes);
        }
    }

    // Sort entries and exits for every room
    for (auto& [employeeID, rooms] : employeeLogs) {
        for (auto& [roomNumber, logs] : rooms) {
            sort(logs.first.begin(), logs.first.end());  // Sort entries
            sort(logs.second.begin(), logs.second.end()); // Sort exits
        }
    }

    return employeeLogs;
}

// Function to calculate work done and consistency
pair<int, bool> calculateWorkDoneAndConsistency(
    const map<int, map<int, pair<vector<int>, vector<int>>>>& employeeLogs,
    map<int, map<int, int>>& workDonePerRoom, int employeeID) {
    
    int totalWorkDone = 0;
    bool isInconsistent = false;

    for (const auto& [roomNumber, logs] : employeeLogs.at(employeeID)) {
        const auto& entries = logs.first;
        const auto& exits = logs.second;

        vector<bool> entryUsed(entries.size(), false);
        vector<bool> exitUsed(exits.size(), false);

        int roomWorkDone = 0;

        // Map exits to the nearest prior entry
        for (size_t j = 0; j < exits.size(); ++j) {
            for (size_t i = 0; i < entries.size(); ++i) {
                if (!entryUsed[i] && entries[i] < exits[j]) {
                    roomWorkDone += exits[j] - entries[i];
                    entryUsed[i] = true;
                    exitUsed[j] = true;
                    break;
                }
            }
        }

        // Check if unmatched entries or exits remain
        if (any_of(entryUsed.begin(), entryUsed.end(), [](bool used) { return !used; }) ||
            any_of(exitUsed.begin(), exitUsed.end(), [](bool used) { return !used; })) {
            isInconsistent = true;
        }

        totalWorkDone += roomWorkDone;
        workDonePerRoom[employeeID][roomNumber] = roomWorkDone;
    }

    return {totalWorkDone, isInconsistent};
}

// Main function
int main() {
    int n;
    cin >> n;

    vector<tuple<int, string, string, string>> logs(n);
    for (int i = 0; i < n; ++i) {
        int employeeID;
        string action, location, time;
        cin >> employeeID >> action >> location >> time;
        logs[i] = {employeeID, action, location, time};
    }

    int suspectID;
    cin >> suspectID;

    // Step 1: Sort logs and organize data
    sort(logs.begin(), logs.end(), [](const auto& a, const auto& b) {
        if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);
        return get<2>(a) < get<2>(b);
    });
    auto employeeLogs = processLogs(logs);

    // Step 2: Calculate work done and consistency for each employee
    map<int, map<int, int>> workDonePerRoom;
    map<int, pair<int, bool>> results; // {EmployeeID: {TotalWorkDone, IsInconsistent}}

    for (const auto& [employeeID, _] : employeeLogs) {
        results[employeeID] = calculateWorkDoneAndConsistency(employeeLogs, workDonePerRoom, employeeID);
    }

    // Step 3: Print individual employee status
    cout << "Employee Status:\n";
    for (const auto& [employeeID, result] : results) {
        const auto& [totalWorkDone, isInconsistent] = result;
        cout << "Employee ID: " << employeeID << "\n";
        cout << "  Consistency: " << (isInconsistent ? "Inconsistent" : "Consistent") << "\n";
        cout << "  Total Work Done: " << totalWorkDone << " minutes\n";
        cout << "  Work Done by Room:\n";
        for (const auto& [room, work] : workDonePerRoom[employeeID]) {
            cout << "    room" << room << ": " << work << " minutes\n";
        }
        cout << "\n";
    }

    // Step 4: Determine result for suspect
    bool suspectInconsistent = results[suspectID].second;
    int suspectWork = results[suspectID].first;
    int leastWork = INT_MAX;
    bool otherInconsistentWithLessWork = false;

    for (const auto& [employeeID, result] : results) {
        const auto& [workDone, isInconsistent] = result;
        if (workDone < leastWork) leastWork = workDone;
        if (employeeID != suspectID && isInconsistent && workDone < suspectWork) {
            otherInconsistentWithLessWork = true;
        }
    }

    if (suspectInconsistent || otherInconsistentWithLessWork) {
        cout << "Cannot be determined\n";
    } else if (suspectWork == leastWork) {
        cout << "Yes\n";
    } else {
        cout << "No\n";
    }

    return 0;
}