人狼羊白菜过河问题算法,C++代码实现

本文介绍了人狼羊白菜过河问题的解决思路,强调保证狼、羊、白菜的安全是首要条件。通过使用标志变量表示它们在岸A、船上或岸B的状态,进而实现算法。给出了C++的代码示例。

      人狼羊白菜过河问题首先是要保证狼羊白菜的存活,然后才是全部过河到对岸,要保证狼羊白菜的存活,就不能在没有人监护的情况下,让他们三者中狼羊,羊白菜在岸的同一端。我们用一个标志来标识人狼羊白菜的位置信息,0表示在岸A(始岸),1表示在船上,2表示在岸B(终岸),弄清楚了问题的关键后,就好动手实现了。示例代码如下:

//TestGuohe.h
#include <iostream>
#include <string>
class Man;
class Object
{
public:
	Object()
	{
		nPos = 0;
	}
public:
	virtual std::string GetType() {return "Object";}
	virtual bool eat(Object *pObj, Man *pMan)
	{
		return false;
	}
public:
	int nPos;
};


class Man
{
public:
	Man()
	{
		nPos = 0;
	}

	virtual std::string GetType() {return "Man";}
	bool GoWith(std::vector<Object *> &vecObj, size_t nIndex) 
	{
		if(nIndex < 0 || nIndex > vecObj.size()-1)
		{
			return false;
		}

		if(nPos != vecObj[nIndex]->nPos)
		{
			return false;
		}
		
		nPos = 1;
		vecObj[nIndex]->nPos = 1;
		for(size_t i = 0; i < vecObj.size(); i++)
		{
			for(size_t j = 0; j < vecObj.size(); j++)
			{
				if(vecObj[i]->eat(vecObj[j],this) == true)
				{
					nPos = 0;
					vecObj[nIndex]->nPos = 0;
					return false;
				}
			}
			
		}
		
		std::string strBorderA = "";
		std::string strOnBoat = GetType()+" ";
		std::string strBorderB = "";
		for(size_t i = 0; i < vecObj.size(); i++)
		{
			if(vecObj[i]->nPos == 0)
			{
				strBorderA += vecObj[i]->GetType()+" ";
			}
			else if(vecObj[i]->nPos == 1)
			{
				strOnBoat += vecObj[i]->GetType() +" ";
			}
			else
			{
				strBorderB += vecObj[i]->GetType() +" ";
			}
		}
		nPos = 2;
		vecObj[nIndex]->nPos = 2;

		std::cout<<"岸A: "<<strBorderA<<" [["<<strOnBoat<<"-------------->]] 岸B: "<<strBorderB<<std::endl;
		return true;
	}

	bool BackWith(std::vector<Object *> &vecObj, size_t nIndex)  
	{
		if(nIndex < 0 || nIndex > vecObj.size()-1)
		{
			return false;
		}

		if(nPos != vecObj[nIndex]->nPos)
		{
			return false;
		}

		nPos = 1;
		vecObj[nIndex]->nPos = 1;
		
		for(size_t i = 0; i < vecObj.size(); i++)
		{
			for(size_t j = 0; j < vecObj.size(); j++)
			{
				if(vecObj[i]->eat(vecObj[j],this) == true)
				{
					nPos = 2;
					vecObj[nIndex]->nPos = 2;
					return false;
				}
			}

		}
		
		std::string strBorderA = "";
		std::string strOnBoat = GetType()+" ";
		std::string strBorderB = "";
		for(size_t i = 0; i < vecObj.size(); i++)
		{
			if(vecObj[i]->nPos == 0)
			{
				strBorderA += vecObj[i]->GetType()+" ";
			}
			else if(vecObj[i]->nPos == 1)
			{
				strOnBoat += vecObj[i]->GetType() +" ";
			}
			else
			{
				strBorderB += vecObj[i]->GetType() +" ";
			}
		}

		nPos = 0;
		vecObj[nIndex]->nPos = 0;
		std::cout<< "岸A: "<<strBorderA<<" [[<-------------"<<strOnBoat<<"]] 岸B: "<<strBorderB<<std::endl;
		return true;
	}

	bool Back(std::vector<Object *> &vecObj)
	{
		nPos = 1;
		for(size_t i = 0; i < vecObj.size(); i++)
		{
			for(size_t j = 0; j < vecObj.size(); j++)
			{
				if(vecObj[i]->eat(vecObj[j],this) == true)
				{
					nPos = 2;
					return false;
				}
			}

		}
		
		std::string strBorderA = "";
		std::string strOnBoat = GetType()+" ";
		std::string strBorderB = "";
		for(size_t i = 0; i < vecObj.size(); i++)
		{
			if(vecObj[i]->nPos == 0)
			{
				strBorderA += vecObj[i]->GetType()+" ";
			}
			else if(vecObj[i]->nPos == 1)
			{
				strOnBoat += vecObj[i]->GetType() +" ";
			}
			else
			{
				strBorderB += vecObj[i]->GetType() +" ";
			}
		}

		nPos = 0;
		std::cout<< "岸A: "<<strBorderA<<" [[<-------------"<<strOnBoat<<"]] 岸B: "<<strBorderB<<std::endl;
		return true;
	}
public:
	int nPos;
};

class Wolf: public Object
{
public:
	Wolf(){};
	bool eat(Object *pObj, Man *pMan)
	{
		if(!pObj|| !pMan)
		{
			return false;
		}

		if(strcmp(pObj->GetType().c_str(),"Sheep") == 0 && nPos == pObj->nPos && pMan->nPos != nPos)
		{
			return true;
		}

		return false;
	}

	std::string GetType() {return "Wolf";}
};

class Sheep: public Object
{
public:
	Sheep(){};
	bool eat(Object *pObj, Man *pMan)
	{
		if(!pObj|| !pMan)
		{
			return false;
		}

		if(strcmp(pObj->GetType().c_str(),"Cabbage") == 0 && nPos == pObj->nPos && pMan->nPos != nPos)
		{
			return true;
		}

		return false;
	}

	std::string GetType() {return "Sheep";}
};

class Cabbage: public Object
{
public:
	Cabbage(){};
	std::string GetType() {return "Cabbage";}
	bool eat(Object *pObj, Man *pMan)
	{
		return false;
	}
};

//TestGuohe.cpp
#include "TestGuohe.h"

class Object;
class Man;
class wolf;
class Sheep;
class Cabbage;

bool AllDone(std::vector<Object *> &vecObject)
{
 size_t nPassed = 0;
 for(size_t index = 0; index < vecObject.size(); index++)
 {
  if(vecObject[index]->nPos == 2)
  {
   nPassed++;
  }
 }

 if(nPassed == vecObject.size())
 {
  return true;
 }

 return false;
}
int _tmain(int argc, _TCHAR* argv[])
{
 Man man;
 Object *pObj1 = new Wolf();
 Object *pObj2 = new Sheep();
 Object *pObj3 = new Cabbage();
 std::vector<Object *> vecObject;
 vecObject.push_back(pObj1);
 vecObject.push_back(pObj2);
 vecObject.push_back(pObj3);
 //开始过河
 size_t i = 0;
 size_t j = 0;
 while(i < vecObject.size())
 {
  if(AllDone(vecObject))
  {
   break;
  }

  if(man.GoWith(vecObject,i))
  {
   if(AllDone(vecObject))
   {
    break;
   }
   
   if(!man.Back(vecObject))
   {
    while(j < vecObject.size())
    {
     if(j != i)
     {
      if(man.BackWith(vecObject,j))
      {
       break;
      }
     }
     
     j++;
     if(j == vecObject.size())
     {
      j = 0;
     }
    }
    
   }
  }

  i++;
  if(i == vecObject.size())
  {
   i = 0;
  }
 }
 
 return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值