/*---------------------------------------------------------------------------
File name: C76-48.cpp
Author: HJin
Created on: 6/18/2007 15:15:52
C76-48.cpp --- the cpp source file for solving the 48th of the 76
classical C/C++ problems.
经典 76 道编程题 之 48:
48. 将4个红球,3个白球与3个黄球排成一排,共有多少种排法?
Answer: binomial(10, 4) * binomial(6, 3) * binomial(3, 3) = 4200.
Analysis:
Allocate r+w+y (=10) slots. The job can be done in three steps:
(1) we put all r red balls into the r+w+y slots --- total is binomial(r+w+y, r)
(2) we put all w white balls into the remaining w+y slots --- total is binomial(w+y, y)
(3) we put all y yellow balls into the remaining y slots --- total is binomial(y, y) = 1
All in all, total is binomial(r+w+y, r) * binomial(w+y, y) * 1.
Programming thoughts:
Generate all 3^(r+w+y) possible choices (since each slot can have one of the
three colors ) and check if a choice is valid. A choice is valid if and only
if there are r red balls, w white balls, and y yellow balls.
We used a set in the implementation, since set does not store duplicates.
Sample output:
1 rrwy
2 rryw
3 rwry
4 rwyr
5 ryrw
6 rywr
7 wrry
8 wryr
9 wyrr
10 yrrw
11 yrwr
12 ywrr
total number of different combinations are 12
Press any key to continue . . .
Reference:
1. 野比, 相当经典的76道编程自虐题分享.无答案 at
http://bbs.bc-cn.net/viewthread.php?tid=147853
*/
#include <iostream>
#include <set>
#include <string>
using namespace std;
string buffer;
/**
Time complexity is O(3^(r+w+y)) --- very inefficient.
build the set of all combinations.
*/
void buildSet(int r, int w, int y, int n, set<string>& s);
/**
wrap the function buildSet() and outputs results.
*/
int combination(int r, int w, int y, bool print = true);
/**
check if the string is valid.
A choice is valid if and only if there are r red balls, w white balls, and
y yellow balls.
*/
bool isValid(int r, int w, int y, string& str);
int main(int argc, char** argv)
{
// test #3
//int r=4;
//int w=3;
//int y=3;
// test #2
//int r=3;
//int w=2;
//int y=2;
// test #1
int r=2;
int w=1;
int y=1;
cout<<"total number of different combinations are "<<combination(r, w, y, true)<<endl;
return 0;
}
void buildSet(int r, int w, int y, int n, set<string>& s)
{
if(n==0)
{
if(isValid(r, w, y, buffer))
{
s.insert(buffer);
}
return;
}
string temp = buffer; // keep previous state
buffer+="r";
buildSet(r, w, y, n-1, s);
buffer = temp; // recall previous state
buffer+="w";
buildSet(r, w, y, n-1, s);
buffer = temp; // recall previous state
buffer+="y";
buildSet(r, w, y, n-1, s);
}
int combination(int r, int w, int y, bool print)
{
set<string> s;
int n = r+w+y;
int counter = 0;
buildSet(r, w, y, n, s);
if(print) // print combinations
{
for(set<string>::const_iterator iter = s.begin(); iter!=s.end(); ++iter)
{
++counter;
cout<<counter<<"\t"<<*iter<<endl;
}
}
return s.size();
}
bool isValid(int r, int w, int y, string& str)
{
int r_=0; // store # of red balls
int w_=0;
int y_=0;
bool res = false;
for(size_t i =0; i<str.size(); ++i)
{
switch(str[i])
{
case 'r':
++r_;
break;
case 'w':
++w_;
break;
case 'y':
++y_;
break;
}
}
res = (r_==r) && (w_==w) && (y_==y);
return res;
}
[此贴子已经被作者于2007-6-19 6:17:01编辑过]
I am working on a system which has no Chinese input. Please don\'t blame me for typing English.