Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <iterator>
- #include <algorithm>
- #include <functional>
- struct Player {
- size_t id;
- int64_t efficiency;
- };
- struct Team {
- std::vector<Player>::iterator start;
- std::vector<Player>::iterator end;
- int64_t efficiency{};
- };
- bool operator<(const Player& lhs, const Player& rhs);
- template <class RandomAccessIterator, class Compare = std::less<typename std::iterator_traits<RandomAccessIterator>::value_type>>
- void MySort(RandomAccessIterator first, RandomAccessIterator last, Compare compare);
- bool CompByEfficiency(const Player& lhs, const Player& rhs);
- bool CompByNumber(const Player& lhs, const Player& rhs);
- int64_t GetTeamEfficiency(const std::vector<Player>& answer_team);
- std::vector<Player> ReadData(std::istream* in);
- std::vector<Player> FindOptimalSolidaryTeam(std::vector<Player> team);
- void WriteAnswer(std::vector<Player> answer_team, std::ostream* out);
- int main() {
- const auto team = ReadData(&std::cin);
- auto optimal_team = FindOptimalSolidaryTeam(team);
- WriteAnswer(optimal_team, &std::cout);
- return 0;
- }
- bool operator<(const Player& lhs, const Player& rhs) {
- return CompByNumber(lhs, rhs);
- }
- template <class RandomAccessIterator, class Compare>
- RandomAccessIterator MyMerge(RandomAccessIterator first,
- RandomAccessIterator middle,
- RandomAccessIterator last,
- RandomAccessIterator merge_result,
- Compare compare) {
- auto merged_start = merge_result;
- auto second_start = middle;
- auto first_start = first;
- while (first_start != second_start && middle != last) {
- if (compare(*first_start, *middle)) {
- *merge_result = *first_start;
- ++first_start;
- } else {
- *merge_result = *middle;
- ++middle;
- }
- ++merge_result;
- }
- merge_result = std::copy(first_start, second_start, merge_result);
- merge_result = std::copy(middle, last, merge_result);
- return std::copy(merged_start, merge_result, first);
- }
- template <class RandomAccessIterator, class Compare>
- void MergeSort(RandomAccessIterator first,
- RandomAccessIterator last,
- const RandomAccessIterator& merge_result,
- Compare compare) {
- if (last - first <= 1) {
- return;
- }
- auto middle = first + (last - first) / 2;
- MergeSort(first, middle, merge_result, compare);
- MergeSort(middle, last, merge_result, compare);
- MyMerge(first, middle, last, merge_result, compare);
- }
- template <class RandomAccessIterator, class Compare>
- void MySort(RandomAccessIterator first, RandomAccessIterator last, Compare compare) {
- std::vector<typename std::iterator_traits<RandomAccessIterator>::value_type> buffer;
- buffer.resize(last - first);
- MergeSort(first, last, buffer.begin(), compare);
- }
- bool CompByEfficiency(const Player& lhs, const Player& rhs) {
- return lhs.efficiency < rhs.efficiency;
- }
- bool CompByNumber(const Player& lhs, const Player& rhs) {
- return lhs.id < rhs.id;
- }
- int64_t GetTeamEfficiency(const std::vector<Player>& answer_team) {
- int64_t summary_efficiency = 0;
- for (const auto& player : answer_team) {
- summary_efficiency += player.efficiency;
- }
- return summary_efficiency;
- }
- std::vector<Player> ReadData(std::istream* in) {
- std::ios_base::sync_with_stdio(false);
- std::cin.tie(nullptr);
- size_t amount_players = 0;
- std::cin >> amount_players;
- std::vector<Player> players;
- int64_t efficiency = 0;
- for (size_t i = 1; i <= amount_players; ++i) {
- *in >> efficiency;
- players.push_back({i, efficiency});
- }
- return players;
- }
- std::vector<Player> FindOptimalSolidaryTeam(std::vector<Player> team) {
- size_t amount_players = team.size();
- if (amount_players < 3) {
- return team;
- }
- MySort(team.begin(), team.end(), CompByEfficiency);
- int64_t curr_efficiency = team.begin()->efficiency + (team.begin() + 1)->efficiency;
- Team cur_team = {team.begin(), team.begin() + 2, curr_efficiency};
- Team optimal_team = cur_team;
- while (cur_team.end != team.end()) {
- ++cur_team.end;
- cur_team.efficiency += (cur_team.end - 1)->efficiency;
- while (cur_team.start + 1 < cur_team.end &&
- cur_team.start->efficiency +
- (cur_team.start + 1)->efficiency < (cur_team.end - 1)->efficiency) {
- cur_team.efficiency -= cur_team.start->efficiency;
- ++cur_team.start;
- }
- if (cur_team.efficiency > optimal_team.efficiency) {
- optimal_team = cur_team;
- }
- }
- return {optimal_team.start, optimal_team.end};
- }
- void WriteAnswer(std::vector<Player> answer_team, std::ostream* out) {
- // MySort(answer_team.begin(), answer_team.end(), CompByNumber);
- MySort(answer_team.begin(), answer_team.end());
- int64_t efficiency = GetTeamEfficiency(answer_team);
- *out << efficiency << "\n";
- for (const auto& player : answer_team) {
- *out << player.id << " ";
- }
- *out << "\n";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement