// UVa 778 - Recording a tape
#include <iostream>
#include <map>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
struct Song {
string l;
int len;
};
vector<int> readCassetteLengths(const string& line, int& max_len) {
istringstream strm(line);
int len;
vector<int> lens;
while (strm >> len) {
len *= 30;
lens.push_back(len);
if (len > max_len)
max_len = len;
}
return lens;
}
vector<Song> readSongLengths(int& songs_total) {
vector<Song> songs;
string line;
getline(cin, line);
while (line != "%") {
istringstream strm(line);
string w;
strm >> w;
int mins = 0;
for (unsigned i = 0; i < w.length(); i++)
if (w[i] >= '0' && w[i] <= '9')
mins = mins * 10 + w[i] - '0';
strm >> w;
int secs = 0;
for (unsigned i = 0; i < w.length(); i++)
if (w[i] >= '0' && w[i] <= '9')
secs = secs * 10 + w[i] - '0';
Song e = { line, mins * 60 + secs };
songs.push_back(e);
songs_total += e.len;
getline(cin, line);
}
return songs;
}
void updateClosests(const vector<int>& lens, int new_gen, vector<int>& closest_to) {
for (int i = 0; i < lens.size(); i++) {
if (closest_to[i] < new_gen && new_gen <= lens[i]) {
closest_to[i] = new_gen;
}
}
}
map<int, int> knapsack(int capacity, const vector<Song>& items, const vector<int>& lens, vector<int>& closest_to) {
map<int, int> generated;
generated[0] = -1;
for (int i = 0; i < items.size(); i++) {
int item = items[i].len;
vector<int> new_gens;
for (map<int, int>::iterator it = generated.begin(); it != generated.end(); ++it) {
int new_gen = it->first + item;
if (generated.count(new_gen) == 0)
new_gens.push_back(new_gen);
}
for (vector<int>::iterator it = new_gens.begin(); it != new_gens.end(); ++it) {
int new_gen = *it;
if (generated.count(new_gen) == 0) {
generated[new_gen] = i + 1;
updateClosests(lens, new_gen, closest_to);
}
}
}
return generated;
}
int getSmallestPossibleLength(const vector<int>& closest_to, const vector<int>& lens, int& songs_total) {
int smallest_possible_length = -1;
for (int i = 0; i < closest_to.size(); i++) {
if (songs_total - closest_to[i] <= lens[i] && (smallest_possible_length == -1 || lens[i] < lens[smallest_possible_length]))
smallest_possible_length = i;
}
return smallest_possible_length;
}
vector<bool> reconstruct(int length, map<int, int>& sack, const vector<Song>& songs) {
vector<bool> used(songs.size());
while (length > 0) {
int item_index = sack[length] - 1;
used[item_index] = true;
length -= songs[item_index].len;
}
return used;
}
void print_side(const vector<bool>& sides, bool this_side, const vector<Song>& songs) {
for (int i = 0; i < sides.size(); i++) {
if (sides[i] == this_side)
cout << songs[i].l << endl;
}
}
int main() {
string line;
while (getline(cin, line)) {
istringstream strm(line);
int max_len = -1;
vector<int> lens = readCassetteLengths(line, max_len);
int songs_total = 0;
vector<Song> songs = readSongLengths(songs_total);
vector<int> closest_to(lens.size());
map<int, int> sack = knapsack(max_len >> 1, songs, lens, closest_to);
int smallest_possible_length = getSmallestPossibleLength(closest_to, lens, songs_total);
cout << lens[smallest_possible_length] / 30 << endl;
vector<bool> sides = reconstruct(closest_to[smallest_possible_length], sack, songs);
cout << "Side A" << endl;
print_side(sides, true, songs);
cout << "Side B" << endl;
print_side(sides, false, songs);
cout << '%' << endl;
}
return 0;
}
Monday, November 7, 2016
UVa 778 - Recording a tape
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment