-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbard.cpp
143 lines (119 loc) · 3.6 KB
/
bard.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/**
* @file bard.cpp
* @author William Weston
* @brief Bard Problem From Kattis
* @version 0.1
* @date 2023-09-18
*
* @copyright Copyright (c) 2023
*
* Link: https://open.kattis.com/problems/bard
*/
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <iterator> // insert_iterator
#include <map>
#include <numeric> // iota
#include <set>
#include <vector>
constexpr auto BARD = 1;
using song_map = std::map<int, std::set<int>>;
auto create_song_map( int number_of_villagers ) -> song_map;
auto exchange_songs( song_map& songs_known, std::vector<int> const& present ) -> void;
auto add_new_song( song_map& songs_known, std::vector<int> const& present, int song_number ) -> void;
auto know_all_songs( song_map const& songs_known, int total_songs ) -> std::vector<int>;
auto is_present( std::vector<int> const& villagers, int villager ) -> bool;
auto print( std::vector<int> const& villagers ) -> void;
auto main() -> int
{
auto const number_of_villagers = [] { int tmp; std::cin >> tmp; return tmp; }();
auto const number_of_evenings = [] { int tmp; std::cin >> tmp; return tmp; }();
auto songs_known = create_song_map( number_of_villagers );
for ( auto evening = 0; evening < number_of_evenings; ++evening )
{
auto const number_present = [] { int tmp; std::cin >> tmp; return tmp; }();
auto present = std::vector<int>();
for ( auto count = 0; count < number_present; ++count )
{
int villager;
std::cin >> villager;
present.push_back( villager );
}
std::sort( present.begin(), present.end() );
if ( is_present( present, BARD ) )
{
add_new_song( songs_known, present, evening );
}
else
{
exchange_songs( songs_known, present );
}
}
auto const total_songs = songs_known[1].size();
auto knows_all = know_all_songs( songs_known, total_songs );
print( knows_all );
return EXIT_SUCCESS;
}
auto
create_song_map( int const number_of_villagers ) -> song_map
{
auto result = song_map();
for ( auto count = 1; count < number_of_villagers + 1; ++count )
{
result[count];
}
return result;
}
auto
exchange_songs( song_map& songs_known, std::vector<int> const& present ) -> void
{
auto song_book = std::set<int>();
// get list of all songs known between those present
for ( auto const villager : present )
{
auto const iter = songs_known.find( villager );
if ( iter != songs_known.end() )
{
auto const& song_set = iter->second;
song_book.insert( song_set.begin(), song_set.end() );
}
}
// add the song book to each villager present's set of songs
for ( auto const villager : present )
{
songs_known[villager].insert( song_book.begin(), song_book.end() );
}
}
auto
add_new_song( song_map& songs_known, std::vector<int> const& present, int const song_number ) -> void
{
for ( auto villager : present )
{
songs_known[villager].insert( song_number );
}
}
auto
know_all_songs( song_map const& songs_known, int const total_songs ) -> std::vector<int>
{
auto result = std::vector<int>();
for ( auto const& [villager, songs] : songs_known )
{
if ( songs.size() == total_songs )
result.push_back( villager );
}
return result;
}
auto
is_present( std::vector<int> const& villagers, int const villager ) -> bool
{
return std::binary_search( villagers.begin(), villagers.end(), villager );
}
auto
print( std::vector<int> const& villagers ) -> void
{
for ( auto const elem : villagers )
{
std::cout << elem << '\n';
}
}