Advertisement
arch239

Football Team

Dec 6th, 2019
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.23 KB | None | 0 0
  1. #include <iostream>
  2. #include <iterator>
  3. #include <random>
  4. #include <vector>
  5.  
  6. struct Player {
  7.     Player(uint32_t number, uint32_t efficiency) : number(number), efficiency(efficiency) {
  8.     }
  9.  
  10.     uint32_t number;
  11.     uint32_t efficiency;
  12. };
  13.  
  14. bool CompareByNumber(const Player& lhs, const Player& rhs) {
  15.     return lhs.number < rhs.number;
  16. }
  17.  
  18. bool CompareByEfficiency(const Player& lhs, const Player& rhs) {
  19.     return lhs.efficiency < rhs.efficiency;
  20. }
  21.  
  22. template <class Iter, class Compare>
  23. Iter Partition(Iter left, Iter right, Iter pivot, Compare comp) {
  24.     std::iter_swap(pivot, left);
  25.     pivot = left;
  26.  
  27.     while (left < right) {
  28.         do {
  29.             ++left;
  30.         } while ((left < right) && comp(*left, *pivot));
  31.  
  32.         do {
  33.             --right;
  34.         } while (comp(*pivot, *right));
  35.  
  36.         if (left < right) {
  37.             std::iter_swap(left, right);
  38.         }
  39.     }
  40.  
  41.     std::iter_swap(pivot, std::prev(left));
  42.     return left;
  43. }
  44.  
  45. template <class Iter, class Compare, class Generator>
  46. void QuickSort(Iter first, Iter last, Compare comp, Generator& generator) {
  47.     while (std::distance(first, last) > 1) {
  48.         std::uniform_int_distribution<int> random_step(0, std::distance(first, last) - 1);
  49.         Iter pivot = std::next(first, random_step(generator));
  50.         Iter partition = Partition(first, last, pivot, comp);
  51.         if (std::distance(first, partition) < std::distance(partition, last)) {
  52.             QuickSort(first, partition, comp, generator);
  53.             first = partition;
  54.         } else {
  55.             QuickSort(partition, last, comp, generator);
  56.             last = partition;
  57.         }
  58.     }
  59. }
  60.  
  61. template <class Iter, class Compare>
  62. void Sort(Iter first, Iter last, Compare comp) {
  63.     std::mt19937 generator(42);
  64.     QuickSort(first, last, comp, generator);
  65. }
  66.  
  67. std::vector<Player> ReadPlayers() {
  68.     int count;
  69.     std::cin >> count;
  70.  
  71.     std::vector<Player> players;
  72.     players.reserve(count);
  73.  
  74.     for (int i = 1; i <= count; ++i) {
  75.         uint32_t efficiency;
  76.         std::cin >> efficiency;
  77.         players.emplace_back(i, efficiency);
  78.     }
  79.  
  80.     return players;
  81. }
  82.  
  83. uint64_t CountTeamEfficiency(std::vector<Player>::iterator first,
  84.                             std::vector<Player>::iterator last) {
  85.     uint64_t team_efficiency = 0;
  86.  
  87.     for (auto it = first; it < last; ++it) {
  88.         team_efficiency += it->efficiency;
  89.     }
  90.  
  91.     return team_efficiency;
  92. }
  93.  
  94. struct Team {
  95.     Team(std::vector<Player>::iterator first, std::vector<Player>::iterator last)
  96.         : efficiency(CountTeamEfficiency(first, last)), first(first), last(last) {
  97.     }
  98.  
  99.     uint64_t efficiency;
  100.     std::vector<Player>::iterator first;
  101.     std::vector<Player>::iterator last;
  102. };
  103.  
  104. std::vector<Player> BuildMostEffectiveSolidaryTeam(std::vector<Player> players) {
  105.     if (players.size() < 3) {
  106.         return players;
  107.     }
  108.  
  109.     Sort(players.begin(), players.end(), CompareByEfficiency);
  110.  
  111.     Team team(players.begin(), std::next(players.begin(), 2));
  112.     Team best_team = team;
  113.  
  114.     while (team.last != players.end()) {
  115.         uint64_t efficiency_of_two_weakest =
  116.             static_cast<uint64_t>(team.first->efficiency) + std::next(team.first)->efficiency;
  117.  
  118.         while ((team.last != players.end()) &&
  119.                (team.last->efficiency <= efficiency_of_two_weakest)) {
  120.  
  121.             team.efficiency += team.last->efficiency;
  122.             ++team.last;
  123.         }
  124.  
  125.         if (team.efficiency > best_team.efficiency) {
  126.             best_team = team;
  127.         }
  128.  
  129.         team.efficiency -= team.first->efficiency;
  130.         ++team.first;
  131.     }
  132.  
  133.     return {best_team.first, best_team.last};
  134. }
  135.  
  136. void WriteTeam(std::vector<Player> team) {
  137.     Sort(team.begin(), team.end(), CompareByNumber);
  138.  
  139.     uint64_t team_efficiency = CountTeamEfficiency(team.begin(), team.end());
  140.     std::cout << team_efficiency << '\n';
  141.  
  142.     for (const Player& player : team) {
  143.         std::cout << player.number << ' ';
  144.     }
  145.  
  146.     std::cout << '\n';
  147. }
  148.  
  149. int main() {
  150.     std::ios_base::sync_with_stdio(false);
  151.     std::cin.tie(nullptr);
  152.  
  153.     std::vector<Player> players = ReadPlayers();
  154.     std::vector<Player> team = BuildMostEffectiveSolidaryTeam(players);
  155.     WriteTeam(team);
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement