USACO Training>My Training>Section 1.4>Mother's Milk
Mother's Milk
Farmer John has three milking buckets of capacity A, B, and C liters.
Each of the numbers A, B, and C is an integer from 1 through 20,
inclusive. Initially, buckets A and B are empty while bucket C is full
of milk. Sometimes, FJ pours milk from one bucket to another until the
second bucket is filled or the first bucket is empty. Once begun, a pour
must be completed, of course. Being thrifty, no milk may be tossed out.
Write a program to help FJ determine what amounts of milk he
can leave in bucket C when he begins with three buckets as above,
pours milk among the buckets for a while, and then notes that bucket
A is empty.
PROGRAM NAME: milk3
INPUT FORMAT
A single line with the three integers A, B, and C.
SAMPLE INPUT (file milk3.in)
8 9 10
OUTPUT FORMAT
A single line with a sorted list of all the possible amounts of
milk that can be in bucket C when bucket A is empty.
SAMPLE OUTPUT (file milk3.out)
1 2 8 9 10
SAMPLE INPUT (file milk3.in)
2 5 10
SAMPLE OUTPUT (file milk3.out)
5 6 7 8 9 10
Solution (Me)
/*
ID: sgospod1
PROG: milk3
LANG: C++
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <set>
#define STANDARD_INPUT
/*#define PRINT_DEBUG*/
#define BUCKET_COUNT 3
#define MAX_AMOUNT 20
using namespace std;
int Capacity[BUCKET_COUNT]; /* 1<=Capacity[i]<=20*/
int Buckets[BUCKET_COUNT] = {0,0,0};
int Amount[MAX_AMOUNT+1];
char done[MAX_AMOUNT+1][MAX_AMOUNT+1][MAX_AMOUNT+1];
#ifdef PRINT_DEBUG
#include <sys/timeb.h>
ofstream log ("log.out");
#endif
bool Done(int* b)
{
if(done[b[0]][b[1]][b[2]]==1) return true;
done[b[0]][b[1]][b[2]] = 1;
return false;
}
void Pour(int* b, int from, int to)
{
#ifdef PRINT_DEBUG
log << "{" << b[0] << "," << b[1] << "," << b[2] << "} " << from << " " << to << endl;
#endif
int m = b[from];
if(Capacity[to]-b[to] < b[from]) m = Capacity[to]-b[to];
b[to] += m;
b[from] -= m;
}
void NextPour(int* b)
{
if(Done(b)) return;
if(b[0]==0)
{
Amount[b[BUCKET_COUNT-1]]=1;
#ifdef PRINT_DEBUG
log << "amount " << b[BUCKET_COUNT-1] << endl;
#endif
}
for(int from=0; from<BUCKET_COUNT; from++)
{
for(int to=0; to<BUCKET_COUNT; to++)
{
int* bb = new int[3];
bb[0]=b[0]; bb[1]=b[1]; bb[2]=b[2];
Pour(bb, from, to);
NextPour(bb);
delete bb;
}
}
}
int main()
{
#ifdef PRINT_DEBUG
struct _timeb timebuf;
char currtime[26];
_ftime_s(&timebuf);
ctime_s( currtime, 26, &(timebuf.time));
cerr << "Start time: " << setw(19) << currtime << "." << timebuf.millitm << endl;
#endif
#ifdef STANDARD_INPUT
istream &fin = cin;
ostream &fout = cout;
#else
ofstream fout ("milk3.out");
ifstream fin ("milk3.in");
#endif
assert(fin != NULL && fout != NULL);
memset(done, 0, (MAX_AMOUNT+1)*(MAX_AMOUNT+1)*(MAX_AMOUNT+1));
memset(Amount, 0, (MAX_AMOUNT+1)*sizeof(int));
for(int i=0; i<BUCKET_COUNT; i++) fin >> Capacity[i];
Buckets[BUCKET_COUNT-1] = Capacity[BUCKET_COUNT-1];
NextPour(Buckets);
int i=0;
for(; i<=MAX_AMOUNT; i++) if(Amount[i]) {fout << i; i++; break;}
for(; i<=MAX_AMOUNT; i++) if(Amount[i]) fout << " " << i;
fout << endl;
#ifdef PRINT_DEBUG
_ftime_s(&timebuf);
ctime_s( currtime, 26, &(timebuf.time));
cerr << "End time : " << setw(19) << currtime << "." << timebuf.millitm << endl;
#endif
return 0;
}
All solutions