L
lhj100
Unregistered / Unconfirmed
GUEST, unregistred user!
题目:有3个分别能装a升,b升,c升的量筒(a与b互质,c>b>a>0)现c筒装满了水,
问能否在c筒中得到 d升的水(c>d>0).
编一程序,实现上述要求,约定:水在各筒之间倒出倒去时没有任何损失.
例如:若a =3,b =7,c =10,要求在c筒中量得 5升的水,可按下述的方法执行
将c筒的水倒满a筒后 a:3 b:0 c;7
a b a:0 b:3 c:7
c a a:3 b:3 c:4
a b a:0 b:6 c:4
c a a:3 b:6 c:1
a b a:2 b:7 c:1
将b筒的水倒满c筒后 a:2 b:0 c:8
a b a:0 b:2 c:8
c a a:3 b:2 c:5
--
1. Cylinder.h:
#ifndef Cylinder_h
#define Cylinder_h
class Cylinder {
private:
int cubage
int reserves
public:
Cylinder(int v){
cubage = v
reserves = 0
}
Cylinder(int c, int r){
cubage = c
reserves = r
}
Cylinder(const Cylinder&
src){
cubage = src.cubage
reserves = src.reserves
}
bool canPourInto(const Cylinder&
dest){
if(!(this->isEmpty()) &&
!(dest.isFull())){
return true
} else
return false
}
void pourInto(Cylinder&
dest){
if(dest.getSpare() >= this->reserves){
dest.reserves += this->reserves
this->reserves =0
} else {
this->reserves -= dest.getSpare()
dest.reserves = dest.cubage
}
}
int getReserves() const{
return reserves
}
int getCubage() const{
return cubage
}
int getSpare() const {
return (cubage - reserves)
}
bool isEmpty() const {
return (reserves==0)
}
bool isFull() const{
return (cubage==reserves)
}
}
#endif
2. WaterProblem.h
#ifndef WaterProblem_h
#define WaterProblem_h
#include <vcl.h>
#include "Cylinder.h"
class OneState{
public:
Cylinder ca, cb, cc
OneState* parentState
AnsiString action
bool expanded
OneState(const Cylinder&
a, const Cylinder&
b, const Cylinder&
c):
ca(a), cb(b), cc(c){
parentState = NULL
expanded = false
}
bool isExpanded(){
return expanded
}
void setExpanded(){
expanded = true
}
AnsiString toString(){
return "Action: "+action+"/t-->/t a="+ca.getReserves()+";b="+
cb.getReserves()+";c="+cc.getReserves()
}
bool equals(const OneState&
dest){
return (ca.getReserves() == dest.ca.getReserves()
&&
cc.getReserves() == dest.cc.getReserves()
&&
cc.getReserves() == dest.cc.getReserves())
}
bool existsIn(TList* container){
for(int i=0
i<container->Count
i++){
OneState* cur = (OneState*)(container->Items)
if(this->equals(*cur)){
return true
}
}
return false
}
TList* getChildrenStates(){
TList* resultList = new TList()
OneState* aChild
if(ca.canPourInto(cb)){
aChild = new OneState(ca, cb, cc)
aChild->ca.pourInto(aChild->cb)
aChild->parentState = this
aChild->action = "a to b"
resultList->Add(aChild)
}
if(ca.canPourInto(cc)){
aChild = new OneState(ca, cb, cc)
aChild->ca.pourInto(aChild->cc)
aChild->parentState = this
aChild->action = "a to c"
resultList->Add(aChild)
}
if(cb.canPourInto(ca)){
aChild = new OneState(ca, cb, cc)
aChild->cb.pourInto(aChild->ca)
aChild->parentState = this
aChild->action = "b to a"
resultList->Add(aChild)
}
if(cb.canPourInto(cc)){
aChild = new OneState(ca, cb, cc)
aChild->cb.pourInto(aChild->cc)
aChild->parentState = this
aChild->action = "b to c"
resultList->Add(aChild)
}
if(cc.canPourInto(ca)){
aChild = new OneState(ca, cb, cc)
aChild->cc.pourInto(aChild->ca)
aChild->parentState = this
aChild->action = "c to a"
resultList->Add(aChild)
}
if(cc.canPourInto(cb)){
aChild = new OneState(ca, cb, cc)
aChild->cc.pourInto(aChild->cb)
aChild->parentState = this
aChild->action = "c to b"
resultList->Add(aChild)
}
return resultList
}
}
class WaterProblem {
private:
Cylinder *a, *b, *c
int d
TStringList *resultStringList
TList *stateContainer
int MaxCommonDivisor(int i1, int i2){
int big, small
if(i1 > i2){
big = i1
small = i2
} else if(i2 > i1){
big = i2
small = i1
} else
return i1
if(big % small ==0)
return small
if(big-small == 1)
return 1
else {
return MaxCommonDivisor(small, big % small)
}
}
public:
WaterProblem(int va, int vb, int vc, int initD){
resultStringList = new TStringList()
stateContainer = new TList()
a = new Cylinder(va)
b = new Cylinder(vb)
c = new Cylinder(vc, vc)
d = initD
}
~WaterProblem(){
delete resultStringList
for(int i=0
i<stateContainer->Count
i++){
delete stateContainer->Items
}
delete stateContainer
}
bool checkStartState(){
return (c->getCubage()>b->getCubage() &&
b->getCubage()>a->getCuubage() &&
a->getCubage()>0 &&
c->getCubage()>d &&
d>0 &&
(MaxCommonDivisor(a->getCubage(), b->getCubage())==1))
}
bool isEndState(OneState&
state){
return (state.cc.getReserves() == d)
}
void solv(){
OneState startState(*a, *b, *c)
bool solved = false
if(isEndState(startState)){
resultStringList->Add(startState.toString())
return
}
stateContainer->Clear()
stateContainer->Add(&startState)
while(!solved){
if(stateContainer->Count==0){
resultStringList->Add("无解!")
return
}
OneState *lastState = (OneState*)(stateContainer->Last())
if(lastState->isExpanded()){
stateContainer->Remove(lastState)
continue
}
lastState->setExpanded()
TList *children = lastState->getChildrenStates()
for(int i=0
i<children->Count
i++){
OneState *child = (OneState*)(children->Items)
if(isEndState(*child)){
solved = true
OneState* pTemp = child
while(pTemp->parentState != NULL){
resultStringList->Insert(0, pTemp->toString())
pTemp = pTemp->parentState
}
return
} else {
if(!child->existsIn(stateContainer))
stateContainer->Add(child)
}
}
}
}
TStringList&
getResultStringList(){
return (*resultStringList)
}
}
#endif
3. main.cpp
...
void __fastcall TForm1::Button1Click(TObject *Sender)
{
WaterProblem problem(3, 7, 10, 5)
if(problem.checkStartState()){
problem.solv()
TStringList&
result = problem.getResultStringList()
ShowMessage(result.Text)
} else {
ShowMessage("参数不对")
}
问能否在c筒中得到 d升的水(c>d>0).
编一程序,实现上述要求,约定:水在各筒之间倒出倒去时没有任何损失.
例如:若a =3,b =7,c =10,要求在c筒中量得 5升的水,可按下述的方法执行
将c筒的水倒满a筒后 a:3 b:0 c;7
a b a:0 b:3 c:7
c a a:3 b:3 c:4
a b a:0 b:6 c:4
c a a:3 b:6 c:1
a b a:2 b:7 c:1
将b筒的水倒满c筒后 a:2 b:0 c:8
a b a:0 b:2 c:8
c a a:3 b:2 c:5
--
1. Cylinder.h:
#ifndef Cylinder_h
#define Cylinder_h
class Cylinder {
private:
int cubage
int reserves
public:
Cylinder(int v){
cubage = v
reserves = 0
}
Cylinder(int c, int r){
cubage = c
reserves = r
}
Cylinder(const Cylinder&
src){
cubage = src.cubage
reserves = src.reserves
}
bool canPourInto(const Cylinder&
dest){
if(!(this->isEmpty()) &&
!(dest.isFull())){
return true
} else
return false
}
void pourInto(Cylinder&
dest){
if(dest.getSpare() >= this->reserves){
dest.reserves += this->reserves
this->reserves =0
} else {
this->reserves -= dest.getSpare()
dest.reserves = dest.cubage
}
}
int getReserves() const{
return reserves
}
int getCubage() const{
return cubage
}
int getSpare() const {
return (cubage - reserves)
}
bool isEmpty() const {
return (reserves==0)
}
bool isFull() const{
return (cubage==reserves)
}
}
#endif
2. WaterProblem.h
#ifndef WaterProblem_h
#define WaterProblem_h
#include <vcl.h>
#include "Cylinder.h"
class OneState{
public:
Cylinder ca, cb, cc
OneState* parentState
AnsiString action
bool expanded
OneState(const Cylinder&
a, const Cylinder&
b, const Cylinder&
c):
ca(a), cb(b), cc(c){
parentState = NULL
expanded = false
}
bool isExpanded(){
return expanded
}
void setExpanded(){
expanded = true
}
AnsiString toString(){
return "Action: "+action+"/t-->/t a="+ca.getReserves()+";b="+
cb.getReserves()+";c="+cc.getReserves()
}
bool equals(const OneState&
dest){
return (ca.getReserves() == dest.ca.getReserves()
&&
cc.getReserves() == dest.cc.getReserves()
&&
cc.getReserves() == dest.cc.getReserves())
}
bool existsIn(TList* container){
for(int i=0
i<container->Count
i++){
OneState* cur = (OneState*)(container->Items)
if(this->equals(*cur)){
return true
}
}
return false
}
TList* getChildrenStates(){
TList* resultList = new TList()
OneState* aChild
if(ca.canPourInto(cb)){
aChild = new OneState(ca, cb, cc)
aChild->ca.pourInto(aChild->cb)
aChild->parentState = this
aChild->action = "a to b"
resultList->Add(aChild)
}
if(ca.canPourInto(cc)){
aChild = new OneState(ca, cb, cc)
aChild->ca.pourInto(aChild->cc)
aChild->parentState = this
aChild->action = "a to c"
resultList->Add(aChild)
}
if(cb.canPourInto(ca)){
aChild = new OneState(ca, cb, cc)
aChild->cb.pourInto(aChild->ca)
aChild->parentState = this
aChild->action = "b to a"
resultList->Add(aChild)
}
if(cb.canPourInto(cc)){
aChild = new OneState(ca, cb, cc)
aChild->cb.pourInto(aChild->cc)
aChild->parentState = this
aChild->action = "b to c"
resultList->Add(aChild)
}
if(cc.canPourInto(ca)){
aChild = new OneState(ca, cb, cc)
aChild->cc.pourInto(aChild->ca)
aChild->parentState = this
aChild->action = "c to a"
resultList->Add(aChild)
}
if(cc.canPourInto(cb)){
aChild = new OneState(ca, cb, cc)
aChild->cc.pourInto(aChild->cb)
aChild->parentState = this
aChild->action = "c to b"
resultList->Add(aChild)
}
return resultList
}
}
class WaterProblem {
private:
Cylinder *a, *b, *c
int d
TStringList *resultStringList
TList *stateContainer
int MaxCommonDivisor(int i1, int i2){
int big, small
if(i1 > i2){
big = i1
small = i2
} else if(i2 > i1){
big = i2
small = i1
} else
return i1
if(big % small ==0)
return small
if(big-small == 1)
return 1
else {
return MaxCommonDivisor(small, big % small)
}
}
public:
WaterProblem(int va, int vb, int vc, int initD){
resultStringList = new TStringList()
stateContainer = new TList()
a = new Cylinder(va)
b = new Cylinder(vb)
c = new Cylinder(vc, vc)
d = initD
}
~WaterProblem(){
delete resultStringList
for(int i=0
i<stateContainer->Count
i++){
delete stateContainer->Items
}
delete stateContainer
}
bool checkStartState(){
return (c->getCubage()>b->getCubage() &&
b->getCubage()>a->getCuubage() &&
a->getCubage()>0 &&
c->getCubage()>d &&
d>0 &&
(MaxCommonDivisor(a->getCubage(), b->getCubage())==1))
}
bool isEndState(OneState&
state){
return (state.cc.getReserves() == d)
}
void solv(){
OneState startState(*a, *b, *c)
bool solved = false
if(isEndState(startState)){
resultStringList->Add(startState.toString())
return
}
stateContainer->Clear()
stateContainer->Add(&startState)
while(!solved){
if(stateContainer->Count==0){
resultStringList->Add("无解!")
return
}
OneState *lastState = (OneState*)(stateContainer->Last())
if(lastState->isExpanded()){
stateContainer->Remove(lastState)
continue
}
lastState->setExpanded()
TList *children = lastState->getChildrenStates()
for(int i=0
i<children->Count
i++){
OneState *child = (OneState*)(children->Items)
if(isEndState(*child)){
solved = true
OneState* pTemp = child
while(pTemp->parentState != NULL){
resultStringList->Insert(0, pTemp->toString())
pTemp = pTemp->parentState
}
return
} else {
if(!child->existsIn(stateContainer))
stateContainer->Add(child)
}
}
}
}
TStringList&
getResultStringList(){
return (*resultStringList)
}
}
#endif
3. main.cpp
...
void __fastcall TForm1::Button1Click(TObject *Sender)
{
WaterProblem problem(3, 7, 10, 5)
if(problem.checkStartState()){
problem.solv()
TStringList&
result = problem.getResultStringList()
ShowMessage(result.Text)
} else {
ShowMessage("参数不对")
}