过河算法(C++)

1.结点类,InWhere
定义如下:
class InWhere   
{
public:
int boat; //船的位置,开始没有加这个,后来发现因为没有人在左边时候船在右边的话

//
 //
BOOL Test();//测试是否能符合结点条件
int father;//爸爸
int mother;//妈妈
int plice;//警察
int son1;//儿子1
int son2;//儿子2
int daughter1;//女儿1
int daughter2;//女儿2
int shife;//土匪(CS打多了,称号改不过来了)
         //重载操作符,很重要.
InWhere & operator =(const InWhere &other);
BOOL operator ==(const InWhere &other);
BOOL operator !=(const InWhere &other);
InWhere();
virtual ~InWhere();
};      
BOOL InWhere::Test()
{
//测试符合场景状况的结点状态
 //必须要有个会驾船的和船在一边
if(father !=boat && mother !=boat && plice !=boat)
   return FALSE;
//如果有人在船上那么船必须为2
//船上最多有2个人而且必须有个m_bCanDriver = TRUE的
int i = 0;
if(daughter1 == 2) i++;
if(daughter2 == 2) i++;
if(son1 == 2) i++;
if(son2 == 2) i++;
if(father == 2) i++;
if(mother == 2) i++;
if(plice == 2) i++;
if(shife == 2) i++;
if(i>2) return FALSE;
if(i != 0 && boat != 2)
return FALSE;
//警察和小偷不在一起时候,小偷会伤害家人
if(shife != plice)
{
   if(daughter1 == shife || daughter2 == shife ||
    son1 == shife || son2 == shife ||
    father == shife || mother == shife)
   return FALSE;
}
 //当爸爸妈妈不在一起时,妈妈骂儿子,爸爸骂女儿
if(mother != father)
{
   if(daughter1 == father || daughter2 == father ||
    son1 == mother || son2 == mother)
   return FALSE;
}
return TRUE;
}
2.MOVE类
BOOL Move::Test(CArray<InWhere, InWhere>& p_Ain)
{
//测试某2点是否能够通过
InWhere a = p_Ain.GetAt(m_nNow);
InWhere b = a;
 InWhere c = p_Ain.GetAt(m_nNext);
InWhere d = c;

int num(0);
//如果是开始在船上的话
if(a.boat == 2)
{
   ++num;
}
if(c.boat == 2)
{
   ++num;
}
//头和尾只能有且有一个在船上
if(num != 1)
   return FALSE;
 //只要在船上的状态等于岸边的状态就表示此路是行的通的

//从船上到岸上的
if(a.boat == 2)
{
   //---*--->*
   if(a.daughter1 == 2)
    a.daughter1 = 3;
   if(a.daughter2 == 2)
    a.daughter2 = 3;
   if(a.father == 2)
    a.father = 3;
   if(a.mother == 2)
    a.mother = 3;
   if(a.plice == 2)
    a.plice = 3;
   if(a.shife == 2)
    a.shife = 3;
   if(a.son1 == 2)
    a.son1 = 3;
   if(a.son2 == 2)
    a.son2 = 3;
   a.boat =3;
   if(a == p_Ain.GetAt(m_nNext))
   return TRUE;
   //*<----*-----
   if(b.daughter1 == 2)
    b.daughter1 = 1;
   if(b.daughter2 == 2)
    b.daughter2 = 1;
   if(b.father == 2)
    b.father = 1;
   if(b.mother == 2)
    b.mother = 1;
   if(b.plice == 2)
    b.plice = 1;
   if(b.shife == 2)
    b.shife = 1;
   if(b.son1 == 2)
    b.son1 = 1;
   if(b.son2 == 2)
    b.son2 = 1;
   b.boat =1;
   if(b == p_Ain.GetAt(m_nNext))
   return TRUE;
  
}
//从岸到船上
if(c.boat == 2)
{
   //----*<---*
   if(c.daughter1 == 2)
    c.daughter1 = 3;
   if(c.daughter2 == 2)
    c.daughter2 = 3;
   if(c.father == 2)
    c.father = 3;
   if(c.mother == 2)
    c.mother = 3;
   if(c.plice == 2)
    c.plice = 3;
   if(c.shife == 2)
    c.shife = 3;
   if(c.son1 == 2)
    c.son1 = 3;
   if(c.son2 == 2)
    c.son2 = 3;
   c.boat =3;
   if(c == p_Ain.GetAt(m_nNow))
   return TRUE;
   //*---->*----
   if(d.daughter1 == 2)
    d.daughter1 = 1;
   if(d.daughter2 == 2)
    d.daughter2 = 1;
   if(d.father == 2)
    d.father = 1;
   if(d.mother == 2)
    d.mother = 1;
   if(d.plice == 2)
    d.plice = 1;
   if(d.shife == 2)
    d.shife = 1;
   if(d.son1 == 2)
    d.son1 = 1;
   if(d.son2 == 2)
    d.son2 = 1;
   d.boat =1;
   if(d == p_Ain.GetAt(m_nNow))
   return TRUE;
 }
return FALSE;

}
3,遍历
void CRiverDlg::OnRiver() 
{
// TODO: Add your control notification handler code here
UpdateData();
if(m_nGoEnd > m_wheres.GetSize()-1)
{
   MessageBox("填入数字错误,这种情况不存在");
   return;
}
 m_bEndFlag = FALSE;    //重置结束标志
m_ListStep.DeleteAllItems();
m_ListStep.SetRedraw(FALSE);

int i(0);
int nItem(0);
CString strInfo;
 //声明结点访问标志
BOOL *Visited = new BOOL[m_wheres.GetSize()];
for(i = 0 ; i<m_wheres.GetSize(); i++)
   Visited[i] = FALSE;
//初始化道路

CArray<int, int> Road;
 //遍历找到结点
GoRiver(Road, m_nGoBegin, m_nGoEnd, m_MoveAll, Visited);
CString saMessage[3] = {"左岸","船上","右岸"};
nItem = 0;
for(i = 0; i<Road.GetSize(); i++)
{
   strInfo.Format("第%d步", i+1);
   nItem = m_ListStep.InsertItem(nItem, strInfo);
   m_ListStep.SetItemText(nItem, 0, strInfo);
   m_ListStep.SetItemText(nItem, 1, saMessage[m_wheres.GetAt(Road.GetAt(i)).father-1]);
   m_ListStep.SetItemText(nItem, 2, saMessage[m_wheres.GetAt(Road.GetAt(i)).mother-1]);
   m_ListStep.SetItemText(nItem, 3, saMessage[m_wheres.GetAt(Road.GetAt(i)).daughter1-1]);
   m_ListStep.SetItemText(nItem, 4, saMessage[m_wheres.GetAt(Road.GetAt(i)).daughter2-1]);
   m_ListStep.SetItemText(nItem, 5, saMessage[m_wheres.GetAt(Road.GetAt(i)).son1-1]);
   m_ListStep.SetItemText(nItem, 6, saMessage[m_wheres.GetAt(Road.GetAt(i)).son2-1]);
   m_ListStep.SetItemText(nItem, 7, saMessage[m_wheres.GetAt(Road.GetAt(i)).plice-1]);
   m_ListStep.SetItemText(nItem, 8, saMessage[m_wheres.GetAt(Road.GetAt(i)).shife-1]);
   m_ListStep.SetItemText(nItem, 9, saMessage[m_wheres.GetAt(Road.GetAt(i)).boat-1]);
   nItem++;
}
 delete[] Visited;
m_ListStep.SetRedraw(TRUE);
m_ListStep.Invalidate();

}
void CRiverDlg::GoRiver(CArray<int,int>& p_Road, int Begin, int End, CArray<Move, Move>& p_MoveAll, BOOL *Visited)
{
//深度遍历图形算法
//此步不需要因为从设置了结束位以后就再也没调用GORIVER了
//if(m_bEndFlag) return;
int i;
Visited[Begin] = TRUE;
//讲其加入到走过的路中
p_Road.Add(Begin);
if(Begin == End)
{
   m_bEndFlag = TRUE;
   MessageBox("找到了从起点通往终点道路");
   return;
}

for(i=0; i<p_MoveAll.GetSize(); i++)
{
   if(p_MoveAll.GetAt(i).m_nNow == Begin)
   {
    if(Visited[p_MoveAll.GetAt(i).m_nNext] == FALSE)
    {
     GoRiver(p_Road, p_MoveAll.GetAt(i).m_nNext, End, p_MoveAll, Visited);
     if(m_bEndFlag) return;
    }
   }
}
 //如果遍历完了还没找到说明此路不通出栈
p_Road.RemoveAt(p_Road.GetSize()-1);
 
}
void CRiverDlg::OnParse() 
{
//找的所有的状态结点位置及所有可以走过的路
// TODO: Add your control notification handler code here
CString strInfo;//信息提示
m_ListRoot.DeleteAllItems();//ROOT清空
m_ListMyRoad.DeleteAllItems();//MYROAD清空
m_wheres.RemoveAll();   //结点清空

InWhere where;    //临时结点
m_ListRoot.SetRedraw(FALSE); //不许重绘图
int AccordNum(0); //序号
int nItem(0);
int i,j,k,l,m,n,o,p,q;
for(i=1; i<4; i++)
   for(j=1; j<4; j++)
    for(k=1; k<4; k++)
     for(l=1; l<4; l++)
      for(m=1; m<4; m++)
       for(n=1; n<4; n++)
        for(o=1; o<4; o++)
         for(p=1; p<4; p++)
          for(q = 1; q<4; q++)
          {
           where.daughter1 = i;
           where.daughter2 = j;
           where.father = k;
           where.mother = l;
           where.plice = m;
           where.shife = n;
           where.son1 = o;
           where.son2 = p;
           where.boat = q;
           if(where.Test())
           {
            strInfo.Format("%d", AccordNum);
            nItem = m_ListRoot.InsertItem(nItem, strInfo);
            m_ListRoot.SetItemText(nItem,0,strInfo);
            strInfo.Format("%d", k);
            m_ListRoot.SetItemText(nItem,1,strInfo);
            strInfo.Format("%d", l);
            m_ListRoot.SetItemText(nItem,2,strInfo);
            strInfo.Format("%d", i);
            m_ListRoot.SetItemText(nItem,3,strInfo);
            strInfo.Format("%d", j);
            m_ListRoot.SetItemText(nItem,4,strInfo);
            strInfo.Format("%d", o);
            m_ListRoot.SetItemText(nItem,5,strInfo);
            strInfo.Format("%d", p);
            m_ListRoot.SetItemText(nItem,6,strInfo);
            strInfo.Format("%d", m);
            m_ListRoot.SetItemText(nItem,7,strInfo);
            strInfo.Format("%d", n);
            m_ListRoot.SetItemText(nItem,8,strInfo);
            strInfo.Format("%d", q);
            m_ListRoot.SetItemText(nItem,9,strInfo);
            m_wheres.Add(where);
            ++AccordNum;
            ++nItem;
           }
          }
   m_ListRoot.SetRedraw(TRUE);
   m_ListRoot.Invalidate();
   m_ListMyRoad.SetRedraw(FALSE);
   strInfo.Format("一共有%d种可能状况", m_wheres.GetSize());
   MessageBox(strInfo);
   m_MoveAll.RemoveAll();
   Move mov;
   AccordNum = 0;
   nItem = 0;
   for(i = 0; i< m_wheres.GetSize(); i++)
    for(j = 0; j< m_wheres.GetSize(); j++)
    {
     mov.m_nNow = i;
     mov.m_nNext = j;
     if(i != j && mov.Test(m_wheres))
     {
      strInfo.Format("%d", AccordNum);
      nItem = m_ListMyRoad.InsertItem(nItem, strInfo);
      m_ListMyRoad.SetItemText(nItem,0,strInfo);
      strInfo.Format("%d->%d", i,j);
      m_ListMyRoad.SetItemText(nItem,1,strInfo);
      m_MoveAll.Add(mov);
      ++AccordNum;
      ++nItem;
     }
    }
    m_ListMyRoad.SetRedraw(TRUE);
    m_ListMyRoad.Invalidate();
   strInfo.Format("一共有%d种可能移动状况", m_MoveAll.GetSize());
   MessageBox(strInfo);
   GetDlgItem(IDC_RIVER)->EnableWindow();
   GetDlgItem(IDC_GOEND)->EnableWindow();
   GetDlgItem(IDC_GOBEGIN)->EnableWindow();
   //设默认值为起点0终点最后m_wheres的最后个
   //设置默认的起点和终点
   m_nGoBegin = 0;
   m_nGoEnd = m_wheres.GetSize()-1;
   UpdateData(FALSE);
}
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值