问题描述
- 倒水算法,c或者c++都可
-
题目:倒水算法
1.指定水杯个数;
2.指定各个水杯的容量;
3.指定各水杯的当前水量;
4.倒水时遵循两个原则:a)将杯子倒满;b)将有水的杯子中的水全部倒干净。
5.最后达到指定的水平。如有4个水杯,每个水杯的容量分别为21、11、8和5,目前装水分别为21、0、0和0,最终要求装水7、7、7和0.
解决方案
http://www.cnblogs.com/cyq1162/archive/2007/08/07/846552.aspx
解决方案二:
//热门智力题 - 打水问题
//基本思想:用小桶容量的倍数对大桶的容量进行取余。
//指导方针:不断用小桶装水倒入大桶,大桶满了立即清空,
//每次判断下二个桶中水的容量是否等于指定容量。
#include<iostream>
#include <vector>
#include<string>
using namespace std;
const string OPERATOR_NAME[7] = {
"装满A桶","装满B桶",
"将A桶清空","将B桶清空",
"A桶中水倒入B桶","B桶中水倒入A桶",
"成功"
};
int main()
{
cout<<"热门智力题 - 打水问题"<<endl;
cout<<" --by MoreWindows( http://blog.csdn.net/MoreWindows )--n"<<endl;
int a_volume, b_volume, goal_volume;
vector<string> record; //记录操作步数
int ai;
int i, a_water, b_water;
cout<<"请输入A桶容量,B桶容量,目标容量:";
cin>>a_volume>>b_volume>>goal_volume;
a_water = b_water = 0; //A桶,B桶中有多少升水
char szTemp[30];
while (true)
{
if (a_water == 0)//A桶没水,就装满水
{
a_water = a_volume;
sprintf(szTemp, " A:%d B:%d", a_water, b_water);
record.push_back(OPERATOR_NAME[0] + szTemp);//fill A
}
else
{
//如果A桶的水比(B桶容量-B桶的水)要多
if (a_water > b_volume - b_water)
{
//A桶的水==A桶的水+B桶的水-B桶容量
a_water = a_water + b_water- b_volume;
b_water = b_volume; //B桶的水装满了
sprintf(szTemp, " A:%d B:%d", a_water, b_water);
record.push_back(OPERATOR_NAME[4] + szTemp);//A->B
if (a_water == goal_volume)
break;
b_water = 0; //将B桶清空
sprintf(szTemp, " A:%d B:%d", a_water, b_water);
record.push_back(OPERATOR_NAME[3] + szTemp);
}
else
{
//B桶的水==A桶的水+B桶的水
b_water += a_water;
a_water = 0;
sprintf(szTemp, " A:%d B:%d", a_water, b_water);
record.push_back(OPERATOR_NAME[4] + szTemp);//A->B
if (b_water == goal_volume)
break;
}
}
}
record.push_back(OPERATOR_NAME[6]); //success
cout<<"n---------------------------------------------------"<<endl;
cout<<"一个可行的倒水方案如下"<<endl;
vector<string>::iterator pos;
for (pos = record.begin(); pos != record.end(); pos++)
cout<<*pos<<endl;
cout<<"---------------------------------------------------"<<endl;
return 0;
}
参考:http://www.acmerblog.com/pour-water-problem-5615.html
解决方案三:
package
{
public class PourWater
{
public function PourWater()
{
}
public static const TAP:int = -1; // 水龙头
public static const OUT:int = -2; // 倒掉水
public static var vCupWater:Vector.<int>;
public static var vVolume:Vector.<int>;
public static var vTargetState:Vector.<int>;
public static var iTargetWater:int;
public static var iTargetCup:int;
public static var vPath:Vector.<Path>;
public static var bFind:Boolean;
public static function findShortPathEx( targets:Array, cupVolume:Array ):void
{
vCupWater = new Vector.<int>( targets.length );
vTargetState = new Vector.<int>( targets.length );
vVolume = new Vector.<int>( cupVolume.length );
bFind = false;
for ( var i:int = 0; i < targets.length; ++i )
{
vTargetState[i] = targets[i];
vVolume[i] = cupVolume[i];
}
InitBfsState();
}
private static var vvAppearedState:Vector.<Vector.<int>>;
private static var vvBfsQueue:Vector.<Vector.<int>>;
private static var vvBfsPath:Vector.<Vector.<Path>>;
private static var iBfsDepth:int = 15;
public static var iCurSteps:int = 0;
private static function InitBfsState():void
{
vvAppearedState = new Vector.<Vector.<int>>;
vvBfsQueue = new Vector.<Vector.<int>>;
vvBfsPath = new Vector.<Vector.<Path>>;
for ( var i:int = 0; i < vVolume.length; ++i )
{
var tempstate:Vector.<int> = copyState( vCupWater );
pourWater( TAP, i, tempstate );
var tempVPath:Vector.<Path> = new Vector.<Path>;
tempVPath.push( new Path( TAP, i ) );
vvAppearedState.push( copyState( tempstate ) );
vvBfsQueue.push( tempstate );
vvBfsPath.push( tempVPath );
if ( isFind( tempstate ) )
{
vPath = copyPath( tempVPath );
bFind = true;
return;
}
}
bfs();
}
private static function bfs():void
{
while( vvBfsQueue.length > 0 )
{
var tempState:Vector.<int> = vvBfsQueue.shift();
var tempPath:Vector.<Path> = vvBfsPath.shift();
iCurSteps = tempPath.length;
if ( tempPath.length > iBfsDepth )
return;
for ( var i:int = TAP; i < vVolume.length; ++i )
{
for ( var j:int = 0; j < vVolume.length; ++j )
{
if ( i == j )
continue;
var nextState:Vector.<int> = copyState( tempState );
if ( pourWater( i, j, nextState ) && !isAppearedState( nextState ) )
{
var nextPath:Vector.<Path> = copyPath( tempPath );
nextPath.push( new Path( i, j ) );
vvAppearedState.push( copyState( nextState ) );
vvBfsQueue.push( nextState );
vvBfsPath.push( nextPath );
trace("------------------------");
traceCurPath( nextPath );
traceCurState( nextState );
trace("------------------------");
if ( isFind( nextState ) )
{
vPath = copyPath( nextPath );
bFind = true;
return;
}
}
}
}
// 从杯子里往外倒水
for ( i = 0; i < vVolume.length; ++i )
{
nextState = copyState( tempState );
if ( nextState[i] > 0 )
{
nextState[i] = 0;
if ( !isAppearedState( nextState ) )
{
nextPath = copyPath( tempPath );
nextPath.push( new Path( i, OUT ) );
vvAppearedState.push( copyState( nextState ) );
vvBfsQueue.push( nextState );
vvBfsPath.push( nextPath );
}
}
}
tempState.length = 0;
tempPath.length = 0;
tempState = null;
tempPath = null;
}
}
private static function pourWater( iFromCup:int, iToCup:int, vCup:Vector.<int> ):Boolean
{
// 目标满了
if ( vCup[iToCup] == vVolume[iToCup] )
return false;
if ( iFromCup != TAP )
{
// 源是空的
if ( vCup[iFromCup] == 0 )
return false;
// 倒水
if ( vCup[iFromCup] >= ( vVolume[iToCup] - vCup[iToCup] ) )
{
vCup[iFromCup] = vCup[iFromCup] - ( vVolume[iToCup] - vCup[iToCup] );
vCup[iToCup] = vVolume[iToCup];
}
else
{
vCup[iToCup] = vCup[iToCup] + vCup[iFromCup];
vCup[iFromCup] = 0;
}
}
else
vCup[iToCup] = vVolume[iToCup];
return true;
}
private static function isFind( state:Vector.<int> ):Boolean
{
for ( var i:int = 0; i < state.length; ++i )
if ( vTargetState[i] != 0 && vTargetState[i] != state[i] )
return false;
return true;
}
private static function isAppearedState( state:Vector.<int> ):Boolean
{
for ( var i:int = 0; i < vvAppearedState.length; ++i )
if ( isEqualState( state, vvAppearedState[i]) )
return true;
return false;
}
private static function isEqualState( stateSrc:Vector.<int>, stateDes:Vector.<int> ):Boolean
{
for ( var i:int = 0; i < stateSrc.length; ++i )
if ( stateSrc[i] != stateDes[i] )
return false;
return true;
}
private static function copyState( state:Vector.<int> ):Vector.<int>
{
var resState:Vector.<int> = new Vector.<int>( state.length );
for ( var i:int = 0; i < state.length; ++i )
resState[i] = state[i];
return resState;
}
private static function copyPath( path:Vector.<Path> ):Vector.<Path>
{
var resPath:Vector.<Path> = new Vector.<Path>( path.length );
for ( var i:int = 0; i < path.length; ++i )
resPath[i] = new Path( path[i].iCupFrom, path[i].iCupTo );
return resPath;
}
public static function tracePath():String
{
var res:String = "";
if ( bFind )
{
res += "找到长度为" + vPath.length + "的路径!" + "n";
for ( var i:int = 0; i < vPath.length; ++i )
{
if ( vPath[i].iCupFrom == TAP )
res += vVolume[vPath[i].iCupTo] + "L杯子到水龙头接水!" + "n";
else if( vPath[i].iCupTo == OUT )
res += vVolume[vPath[i].iCupFrom] + "L杯子倒掉水!" + "n";
else
res += vVolume[vPath[i].iCupFrom] + "L杯子往"+ vVolume[vPath[i].iCupTo] + "L杯子倒水!" + "n";
}
}
else
res += "经过深度为" + iCurSteps + "的广度优先搜索,没有找到结果!" + "n";
return res;
}
public static function traceCurState( state:Vector.<int> ):void
{
var resStr:String = new String;
for ( var i:int = 0; i < state.length; ++i )
resStr += state[i] + "L#" + vVolume[i] + "L杯子,";
trace( resStr );
}
public static function traceCurPath( path:Vector.<Path> ):void
{
var resStr:String = new String;
for ( var i:int = 0; i < path.length; ++i )
{
if ( path[i].iCupFrom == TAP )
resStr += "水龙头" + "->" + vVolume[path[i].iCupTo] + "L杯子,";
else if( path[i].iCupTo == OUT )
resStr += vVolume[path[i].iCupFrom] + "L杯子" + "倒掉水,";
else
resStr += vVolume[path[i].iCupFrom] + "L杯子->" + vVolume[path[i].iCupTo] + "L杯子,";
}
trace( resStr );
}
}
}
时间: 2024-09-20 03:46:15