Advertisement
Guest User

Untitled

a guest
Oct 13th, 2015
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.76 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <functional>
  5. #include <stdint.h>
  6.  
  7. namespace HeapSort {
  8.     template<typename T>
  9.     struct StdSwap {
  10.         void operator()(T &a, T &b) {
  11.             std::swap(a, b);
  12.         }
  13.     };
  14.  
  15.     template<typename T, typename Compare = std::less<T>, typename Swap = StdSwap<T> >
  16.     class Heap {
  17.     public:
  18.         explicit Heap(Compare compare, Swap swap)
  19.                 : comparator_(compare), swap_(swap) { }
  20.  
  21.         void Insert(const T &value) {
  22.             data_.push_back(value);
  23.             ShiftUp(data_.size() - 1);
  24.         }
  25.  
  26.         void Erase(const int index) {
  27.             swap_(data_[index], data_[data_.size() - 1]);
  28.             data_.pop_back();
  29.             if (index != data_.size()) {
  30.                 ShiftDown(index);
  31.                 ShiftUp(index);
  32.             }
  33.         }
  34.  
  35.         void PopMax() {
  36.             Erase(0);
  37.         }
  38.  
  39.         int GetSize() const {
  40.             return data_.size();
  41.         }
  42.  
  43.     private:
  44.         static int ComputeLeftSonIndex(const int index) {
  45.             return 2 * index + 1;
  46.         }
  47.  
  48.         static int ComputeRightSonIndex(const int index) {
  49.             return 2 * index + 2;
  50.         }
  51.  
  52.         static int ComputeParentIndex(const int index) {
  53.             return (index - 1) / 2;
  54.         }
  55.  
  56.         void ShiftDown(const int index) {
  57.             int max = index;
  58.             if (ComputeLeftSonIndex(index) < data_.size()
  59.                 && comparator_(data_[max], data_[ComputeLeftSonIndex(index)])) {
  60.                 max = ComputeLeftSonIndex(index);
  61.             }
  62.             if (ComputeRightSonIndex(index) < data_.size()
  63.                 && comparator_(data_[max], data_[ComputeRightSonIndex(index)])) {
  64.                 max = ComputeRightSonIndex(index);
  65.             }
  66.             if (max != index) {
  67.                 swap_(data_[index], data_[max]);
  68.                 ShiftDown(max);
  69.             }
  70.         }
  71.  
  72.         void ShiftUp(const int index) {
  73.             if (index && comparator_(data_[ComputeParentIndex(index)], data_[index])) {
  74.                 swap_(data_[ComputeParentIndex(index)], data_[index]);
  75.                 ShiftUp(ComputeParentIndex(index));
  76.             }
  77.         }
  78.  
  79.         std::vector<T> data_;
  80.         Compare comparator_;
  81.         Swap swap_;
  82.     };
  83.  
  84.     template<typename T, typename Compare, typename Swap>
  85.     Heap<T, Compare, Swap> MakeHeap(Compare compare, Swap swap) {
  86.         return Heap<T, Compare, Swap>(compare, swap);
  87.     }
  88.  
  89.  
  90.     template<typename ForwardIterator>
  91.     struct IteratorSwap {
  92.         void operator()(ForwardIterator &first, ForwardIterator &second) {
  93.             std::swap(*first, *second);
  94.         }
  95.     };
  96.  
  97.     template<typename ForwardIterator, typename Compare>
  98.     struct IteratorCompare {
  99.     private:
  100.         Compare cmp;
  101.     public:
  102.         IteratorCompare(Compare _cmp) : cmp(_cmp) { }
  103.  
  104.         bool operator()(ForwardIterator a, ForwardIterator b) {
  105.             return cmp(*a, *b);
  106.         }
  107.     };
  108.  
  109.     template<typename ForwardIterator, typename Compare>
  110.     void Sort(ForwardIterator begin, ForwardIterator end, Compare compare =
  111.         [](ForwardIterator first, ForwardIterator second) {
  112.             return *first < *second;
  113.         }
  114.     ) {
  115.         auto heap = MakeHeap<ForwardIterator>(
  116.                 IteratorCompare<ForwardIterator, Compare>(compare),
  117.                 IteratorSwap<ForwardIterator>()
  118.         );
  119.  
  120.         for (auto it = begin; it != end; ++it)
  121.             heap.Insert(it);
  122.  
  123.         while (heap.GetSize()) {
  124.             heap.PopMax();
  125.         }
  126.     }
  127.  
  128. }
  129.  
  130. struct FootballPlayer {
  131.     int efficiency;
  132.     int id;
  133.  
  134.     explicit FootballPlayer(const int efficiency = 0, const int id = 0) {
  135.         this->efficiency = efficiency;
  136.         this->id = id;
  137.     }
  138. };
  139.  
  140. static bool IsFootballPlayerLessEfficient(const FootballPlayer &first,
  141.                                           const FootballPlayer &second) {
  142.     if (first.efficiency < second.efficiency) {
  143.         return true;
  144.     }
  145.     if (first.efficiency > second.efficiency) {
  146.         return false;
  147.     }
  148.     return (first.id < second.id);
  149. }
  150.  
  151. static bool IsFootballPlayerHasLessId(const FootballPlayer &first,
  152.                                       const FootballPlayer &second) {
  153.     if (first.id < second.id) {
  154.         return true;
  155.     }
  156.     return false;
  157. }
  158.  
  159. std::vector<FootballPlayer> FindMostEfficientSolidarityTeam(std::vector<FootballPlayer> players) {
  160.     HeapSort::Sort(players.begin(), players.end(), IsFootballPlayerLessEfficient);
  161.  
  162.     std::vector<FootballPlayer>::iterator left = players.begin();
  163.     std::vector<FootballPlayer>::iterator right = left + 1;
  164.     std::vector<FootballPlayer>::iterator end = players.end();
  165.     std::vector<FootballPlayer>::iterator save_left = left;
  166.     std::vector<FootballPlayer>::iterator save_right = right;
  167.  
  168.     int64_t save_sum;
  169.     int64_t sum = save_sum = left->efficiency;
  170.     while (right != end) {
  171.         while (right != end && 1ll * (left->efficiency) +
  172.                                (left + 1)->efficiency >= right->efficiency) {
  173.             sum += right->efficiency;
  174.             right++;
  175.         }
  176.         if (sum > save_sum) {
  177.             save_sum = sum, save_left = left, save_right = right;
  178.         }
  179.         sum -= left->efficiency;
  180.         left++;
  181.     }
  182.     std::vector<FootballPlayer> most_efficient_team;
  183.     while (save_left != save_right) {
  184.         most_efficient_team.push_back(*save_left);
  185.         save_left++;
  186.     }
  187.     HeapSort::Sort(most_efficient_team.begin(), most_efficient_team.end(), IsFootballPlayerHasLessId);
  188.     return most_efficient_team;
  189. }
  190.  
  191. int64_t FindTotalEffeciency(const std::vector<FootballPlayer> &team) {
  192.     int64_t sum = 0;
  193.     for (int i = 0; i < team.size(); ++i) {
  194.         sum += team[i].efficiency;
  195.     }
  196.     return sum;
  197. }
  198.  
  199. std::vector<FootballPlayer> InputPlayers(std::istream &input_stream) {
  200.     int number;
  201.     input_stream >> number;
  202.     std::vector<FootballPlayer> players(0);
  203.     for (int i = 0; i < number; ++i) {
  204.         int efficiency;
  205.         input_stream >> efficiency;
  206.         players.push_back(FootballPlayer(efficiency, i));
  207.     }
  208.     return players;
  209. }
  210.  
  211. void OutputMostEffecientTeam(const std::vector<FootballPlayer> &team,
  212.                              std::ostream &output_stream) {
  213.     output_stream << FindTotalEffeciency(team) << std::endl;
  214.     for (int i = 0; i < team.size(); ++i) {
  215.         output_stream << team[i].id + 1 << " ";
  216.     }
  217.     output_stream << std::endl;
  218. }
  219.  
  220. int main() {
  221.     std::vector<FootballPlayer> players = InputPlayers(std::cin);
  222.     std::vector<FootballPlayer> most_efficient_team = FindMostEfficientSolidarityTeam(players);
  223.     OutputMostEffecientTeam(most_efficient_team, std::cout);
  224.     return 0;
  225. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement