BFS

分油算法:一个桶中有12斤油,要求倒出6斤,可现在另外只有两个桶,分别可装8斤与5斤,请问应如何来倒? 
补充:这里的12,6,8,5都是变量,应该可以自己设置,输出是每一次分油的步骤.

 

其实也就一个广度搜索(BFS)。 
从初始状态(12,0,0)到最终有某一个数是6就行了。 
3个桶A、B、C,关系只有6种,A->B(A倒入B),B->C,c->A还有反过来倒。 
从某个状态扩展出6个新的状态直至达到目标状态。 
为了避免重复搜索,可以加个3维数组state[i][j][k]用以表示状态(i,j,k)已经出现,不用对它进行扩展(程序中表现为不入队)。

 

 

#include "stdafx.h" 

 

#include  <iostream>  

#include  <cstring> //  for  memset  and  memcmp  

 

#define  MIN(a,b)  (((a)  <  (b))  ?  (a)  :  (b))  

#define  HASH(s)  hash[s.vol[0]][s.vol[1]][s.vol[2]]  

 

struct  state  

{  

int  vol[3];  

int  depth;  

int  parent;  

};  

 

//瓶子的容量 

const  int  capacity[3]  =  {12,  8,  5};  

const  int  QUEUE_SIZE  =  100000;  

 

state  queue[QUEUE_SIZE]; //  for  bfs  

 

void  print_answer(int  k)  

{  

int  stack[100];  

int  p  =  0;  

int  j;  

 

while  (k  !=  -1)  

{  

stack[p++]  =  k;  

k  =  queue[k].parent;  

}  

 

while  (p--)  

{  

std::cout  <<  "Step  "  <<  queue[stack[p]].depth  <<  ":/t";  

 

for  (j=0;  j <3;  j++)  

{  

std::cout  <<  queue[stack[p]].vol[j]  <<  '/t';  

}  

 

std::cout  <<  std::endl;  

}  

}  

 

int  main(void)  

{  

static  short  int  hash[100][100][100]; //  for  quick  check  

state  start,  target,  current;  

 

int  open,  tail;  

int  i,  j;  

int  delta;  

 

//  data  set  

start.vol[0]  =  12;  //开始时油的体积 

start.vol[1]  =  0;  

start.vol[2]  =  0;  

start.depth  =  0;  

start.parent  =  -1;  

 

target.vol[0]  =  6;  //结果的存放,目前是第一个瓶和第二瓶存放6 

target.vol[1]  =  6;  

target.vol[2]  =  0;  

 

//  initialization  

memset(hash,  0,  sizeof(hash));  

queue[0]  =  start;  

open  =  0,  tail  =  1;  

HASH(start)  =  1;  

 

//  bfs  search!  

while  (open  <  tail)  

{  

for  (i=0;  i <3;  i++)  

{  

for  (j=0;  j <3;  j++)  

{  

if  (i  !=  j)  

{  

current  =  queue[open];  

 

//  from  i  to  j 

delta  =  MIN(current.vol[i],  capacity[j]  -  current.vol[j]);  

current.vol[i]  -=  delta;  

current.vol[j]  +=  delta;  

 

if  (!HASH(current))  //  not  duplicated  

{  

current.depth++;  

current.parent  =  open;  

queue[tail++]  =  current; //  enqueue  

HASH(current)  =  1;  

 

if  (memcmp(&current.vol,  &target.vol,  sizeof(current.vol))

 ==  0) //  got  it  

{  

print_answer(tail  -  1);  

return  0;  

}  

}  

}  //end if(i != j)

}  //end for(j=0;....

}  //end for(i=0;...

 

open++;   // Dequeue

}  

 

std::cout  <<  "no  solution  found"  <<  std::endl;  

return  1;  

}  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值