Ranking (as of 2013-03-17): 34
Language: C++
/*
UVa 565 - Pizza Anyone?
To build using Visual Studio 2008:
cl -EHsc -O2 pizza_anyone.cpp
*/
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#ifdef DEBUG
#include <cassert>
#endif
using namespace std;
const int nr_topping_constraints_default = 12;
int nr_topping_constraints,
nr_topping_constraints_max = nr_topping_constraints_default;
struct topping_constraint {
int nr_; // number of constraints
unsigned int constraints_;
topping_constraint() : nr_(0), constraints_(0) {}
/*
Each constraint for a topping is represented the consecutive two bits, where
the lower bit is for without the topping and the higher bit is for
with the topping.
*/
bool operator<(const topping_constraint& tp) const {return nr_ < tp.nr_;}
};
vector<topping_constraint> topping_constraints(nr_topping_constraints_max);
void parse_topping_constraint(const char* s, topping_constraint& tc)
{
tc.nr_ = 0; tc.constraints_ = 0;
do {
bool with_topping = *s++ == '+';
int shift = (*s++ - 'A') * 2;
unsigned int current = (tc.constraints_ >> shift) & 3;
if (with_topping) {
if (current == 1) { // without the topping
tc.nr_--;
tc.constraints_ &= ~(1 << shift);
}
else if (!current) {
tc.nr_++;
tc.constraints_ |= 2 << shift;
}
}
else {
if (current == 2) { // with the topping
tc.nr_--;
tc.constraints_ &= ~(2 << shift);
}
else if (!current) {
tc.nr_++;
tc.constraints_ |= 1 << shift;
}
}
} while (*s != ';');
}
bool accept_constraints(int tci, unsigned int constraints,
unsigned int& accepted_constraints)
{
if (tci == nr_topping_constraints) {
accepted_constraints = constraints;
return true;
}
/*
From topping_constraints[tci], add a topping constraint that is not
inconsistent with the constraints that have already been set
in constraints
*/
topping_constraint& tc = topping_constraints[tci];
unsigned int c = tc.constraints_;
if (c & constraints)
// at least one topping constraint has already been satisfied
return accept_constraints(tci + 1, constraints, accepted_constraints);
bool successful = false;
unsigned int mask = 3;
for (int nr = tc.nr_; nr; mask <<= 2) {
unsigned int current = constraints & mask, request = c & mask;
if (request) {
nr--;
if (!current) { // a topping constraint has yet not been set
constraints |= request;
successful =
accept_constraints(tci + 1, constraints, accepted_constraints);
constraints &= ~request;
}
if (successful)
break;
}
}
return successful;
}
void print_toppings(unsigned int constraints)
{
cout << "Toppings:";
bool printed = false;
for (int i = 0; constraints; i++, constraints >>= 2)
if (constraints & 2) { // with a topping
if (!printed) {
printed = true;
cout << ' ';
}
cout << static_cast<char>('A' + i);
}
cout << '\n';
}
#ifdef DEBUG
bool verify_constraints(unsigned int constraints)
{
for (int i = 0; i < nr_topping_constraints; i++) {
topping_constraint& tc = topping_constraints[i];
unsigned int c = tc.constraints_;
unsigned int mask = 3;
bool satisfied = false;
for (int nr = tc.nr_; nr; mask <<= 2) {
unsigned int current = constraints & mask, request = c & mask;
if (request) {
nr--;
if (current == request) {
satisfied = true; break;
}
}
}
if (!satisfied)
return false;
}
return true;
}
#endif
int main()
{
string s;
while (cin >> s) {
nr_topping_constraints = 0;
do {
if (nr_topping_constraints >= nr_topping_constraints_max) {
nr_topping_constraints_max++;
topping_constraints.push_back(topping_constraint());
}
parse_topping_constraint(s.c_str(),
topping_constraints[nr_topping_constraints]);
nr_topping_constraints++;
cin >> s;
} while (s[0] != '.');
// sort the topping constraints in ascending order of
// their number of constraints
sort(topping_constraints.begin(),
topping_constraints.begin() + nr_topping_constraints);
unsigned int accepted_constraints = 0;
if (accept_constraints(0, 0, accepted_constraints)) {
print_toppings(accepted_constraints);
#ifdef DEBUG
assert(verify_constraints(accepted_constraints));
#endif
}
else
cout << "No pizza can satisfy these requests.\n";
}
return 0;
}
No comments:
Post a Comment