平分油的问题:(广度优先的算法)

平分油的问题:(广度优先的算法)

问题的描述:一个人体积为30 升的油桶,装满了油,另有两个完全空的桶,一个体积为17升,另一个体积为13升。试用c++面向程序设计的类结构写出程序,求解油的平分最少的步骤,输出平分时的具体的倒油过程。
注:油的平分结构为30升的桶里面有15升的 油,17升的桶里面有15升的油。
C++STL——queue的使用方法
queue模板类的定义在头文件中。queue模板类需要两个模板参数,一个是元素类型,一个是容器类型,袁术类型是不要的,容器类型是可选的,默认为双向队列类型。
定义queue对象的示列代码如下:
queueq1;
queueq2;
queue的基本操作有:
入队,如例:q.push(x)
出队,如例:q.pop()
访问队首元素,如例:q.front();
访问队尾元素,如例:q.back();
判断队列空,如例:q.empty();
访问队列中的元素个数,如例:q.size();

采用广度优先搜索的算法,具体步骤如下:
(1)把初始状态(30,0,0)加入队列;
(2)当队列不空时,重复(3)~(5)步。
(3)从队列中取出一个状态,作为当前状态。
(4)如果当前状态是终态(15,15,0)
输出分油的步骤数及分油的过程,程序结束
(5)进行分油的操作
分别将其中的一个容器的油,倒入其他的容器,如果出现新的状态,将新状态加入队列(新状态的步骤数是在原状态的步骤数的基础上加一)。
(6)结束

代码实现如下:

#include
#include
#include
#include
using namespace std;
class Status{
public:
	int vol[3];//三个容器中的油量
	int step;//从初始状态到当前状态的步骤数
	string str;//从初始状态到当前状态的操作过程,倒油的过程
	//Status();//构造无参的函数
	Status(int step,int V30,int V17,int V13,string str);//构造函数 
};
//无参构造函数
//Status::Status(int step,int V30,int V17,int V13,string str){
//	step=0;
//	vol[0]=vol[1]=vol[2]=0;
//	str="";
//}
//构造有参函数
Status::Status(int step,int V30,int V17,int V13,string str){
	this->step=step;
	vol[0]=V30;
	vol[1]=V17;
	vol[2]=V13;
	this->str=str;
}

int size[]={30,17,13};//定义油桶的体积
queue<Status>q;//存放平分过程的中间状态的队列
bool vis[30][17][13];//用来判断当前的节点是否处理过
void dfs()
{
	while(!q.empty())//如果队列不为空,表示还没有到达平分状态
	{
		Status now =q.front();//队列中取出一个状态,继续平分
		q.pop();
	if(now.vol[0]==15&&now.vol[1]==15){//判断是否平分了油,30升的桶和17升的桶都同时装了15升的油
		cout<<now.step<<endl<<now.str;//输出操作步数,和操作状态
		break;
	}
	for(int i=0;i<3;i++){//两个循环,由第i个桶向j个桶里面倒油
		for( int j=0;j<3;j++){
			if(i!=j&&now.vol[i]>0&&now.vol[j]<size[j]){//不能自己到给自己,同时30升的桶不能为0,其他两个桶没有装满
				int temp=min(now.vol[i],size[j]-now.vol[j]);//计算能倒入的油量(倒油不能只到一半,要么30升的桶到完,要么17或13升的桶装满)
				Status nxt=now;//nxt:将容器i倒入容器j后,进入下一个状态
				nxt.vol[i]-=temp;
				nxt.vol[j]+=temp;
				nxt.step++;
				char op[30];
				//记录操作过程
				sprintf(op,"(%d)->(%d)\n",size[i],size[j]);
				nxt.str+=op;
				if(!vis[nxt.vol[0]][nxt.vol[1]][nxt.vol[2]]){//如果这个转态没有出现过,就把他输入队列
					q.push(nxt);
					vis[nxt.vol[0]][nxt.vol[1]][nxt.vol[2]]=true;
				}
			}
		}
	}
}
}
int main(){	
	q.push(Status(0,30,0,0,""));//无法从“int”转换为“status 解决:注释掉了无参的构造函数 (就是把第一个节点中的树拿出来了)
	vis[30][0][0]=true;//第一个节点先置为true,不遍历了
	dfs();//调用dfs函数
	return 0;
}

结果显示:
平分油的问题:(广度优先的算法)_第1张图片

你可能感兴趣的:(C++,c++,算法)