已知桶、罐和瓶分别能才盛油5000克、3500克、1500克,现在桶中有5000克油,如何只利用这三件容器把油分成成两分,每份2500千克。
问题分析:由于没有刻度的存在,所以对于容器A和B之间,由A向B中倒油,只有如下两种情况的操作:
1.用A中的油把B填满;
2.把A中的油倒尽,全部倒入B中;
这样我们才能控制每个容器中的油量的多少。
状态描述:三元组(A,B,C)
A:桶中的油量
B:罐中的油量
C:瓶中的油量
初始状态:(5000,0,0) 终止状态:(2500,2500,0)
产生式规则:
R1: A fill B
IF <(A>=(3500-B) and (B!=3500))> THEN A=A-3500+B,B=3500
R2: A all to B
IF <(A<(3500-B)) and (B!=0)> THEN A=0,B=B+A
R3: A fill C
IF<(C!=1500)> THEN C=1500,A=A-(1500-C)
R4: B all to A
IF <(B!=0)> THEN A=A+B,B=0
R5: B fill C
IF<(B>=(1500-C)) and (C!=1500)> THEN B=B-(1500-C),C=1500
R6: B all to C
IF <(B<(1500-C)) and (B!=0)> THEN B=0,C=C+B
R7: C all to A
IF <(C!=0)> THEN A=A+C,C=0
R8: C fill B
IF <(C>=(3500-B)) and (B!=3500)> THEN C=C-(3500-B),B=3500
R9: C all to B
IF<(C<(3500-B)) and (C!=0)> THEN B=B+C,C=0
代码附上:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define QueueSize (1024*1024)
typedef enum {R1=0,R2,R3,R4,R5,R6,R7,R8,R9} production;
typedef struct state {
state * parent;
state * child[9];
int pro;
int a;
int b;
int c;
} * pState;
pState root;
state * newState(state * p,int a,int b,int c,int pro)
{
state * pnew=(state *)malloc(sizeof(state));
pnew->parent=p;
pnew->a=a;
pnew->b=b;
pnew->c=c;
pnew->pro=pro;
for(int i=0;i<9;i++)
{
pnew->child[i]=NULL;
}
return pnew;
}
struct {
state ** data;
int header,tailer,size;
}BFSQueue;
void InitQueue()
{
BFSQueue.data=(state **)malloc(QueueSize*sizeof(state *));
BFSQueue.header=BFSQueue.tailer=0;
BFSQueue.size=QueueSize;
}
void EnQueue(state * p)
{
if((BFSQueue.tailer+1)%BFSQueue.size==BFSQueue.tailer){printf("Queue OverFlow!!"); return;}
BFSQueue.data[BFSQueue.tailer]=p;
BFSQueue.tailer=(BFSQueue.tailer+1)%BFSQueue.size;
}
state * DeQueue()
{
if (BFSQueue.header==BFSQueue.tailer)
{
return NULL;
}
state *tmp=BFSQueue.data[BFSQueue.header];
BFSQueue.header=(BFSQueue.header+1)%BFSQueue.size;
return tmp;
}
state * popStack()
{
if(BFSQueue.header==BFSQueue.tailer)
{
return NULL;
}
BFSQueue.tailer=(BFSQueue.tailer-1+BFSQueue.size)%BFSQueue.size;
state *tmp=BFSQueue.data[BFSQueue.tailer];
return tmp;
}
unsigned char * ExistState;
void bit_set(int value)
{
ExistState[value>>3]=ExistState[value>>3]|(0x01<<(value&0x07));
}
bool bit_test(int value)
{
//如果当前位为1返回假
if((ExistState[value>>3]&(0x01<<(value&0x07))))
{
return true;
}
return false;
}
void InitPruning()
{
int value=11*8*4;
ExistState=(unsigned char*)malloc((value)*sizeof(char)>>3);
memset(ExistState,NULL,(value>>3));
}
bool pruning(state * p)
{
if (p==NULL)
{
return false;
}
int value=(p->a/500)*8*4+(p->b/500)*4+(p->c/500);
//printf("Value:%d ",value);
if (bit_test(value))
{
//printf("false\n");
return false;
}
//printf("true\n");
bit_set(value);
return true;
}
void outputResult(state * end)
{
state * tmp=end;
int line=0;
while(tmp->parent!=NULL)
{
EnQueue(tmp);
tmp=tmp->parent;
}
printf("%d (a,b,c):(%d,%d,%d)\n",line++,tmp->a,tmp->b,tmp->c);
while((tmp=popStack())!=NULL)
{
printf("%d (a,b,c):(%d,%d,%d)\n",line++,tmp->a,tmp->b,tmp->c);
}
//printf("%d %d",BFSQueue.header,BFSQueue.tailer);
}
void ExpandTree(state * p)
{
int a=p->a;
int b=p->b;
int c=p->c;
if(a>=(3500-b)&&b!=3500){
p->child[0]=newState(p,a-3500+b,3500,c,R1);
}
if(a<(3500-b)&&a!=0){
p->child[1]=newState(p,0,b+a,c,R2);
}
if(c!=1500){
p->child[2]=newState(p,a-(1500-c),b,1500,R3);
}
if(b!=0){
p->child[3]=newState(p,a+b,0,c,R4);
}
if(b>=(1500-c)&&c!=1500){
p->child[4]=newState(p,a,b-(1500-c),1500,R5);
}
if(b<(1500-c)&&b!=0){
p->child[5]=newState(p,a,0,c+b,R6);
}
if(c!=0){
p->child[6]=newState(p,a+c,b,0,R7);
}
if(c>=(3500-b)&&b!=3500){
p->child[7]=newState(p,a,3500,c-(3500-b),R8);
}
if(c<(3500-b)&&c!=0){
p->child[8]=newState(p,a,b+c,0,R9);
}
for (int i=0;i<9;i++)
{
if(pruning(p->child[i]))
{
//printf("In Queue:(%d,%d,%d)\n",p->child[i]->a,p->child[i]->b,p->child[i]->c);
EnQueue(p->child[i]);
}
if(p->child[i]!=NULL&&(p->child[i]->a==2500&&p->child[i]->b==2500))
{
BFSQueue.header=BFSQueue.tailer;
outputResult(p->child[i]);
//getchar();
break;
}
}
}
int main()
{
root=newState(NULL,5000,0,0,-1);
InitQueue();
InitPruning();
EnQueue(root);
pruning(root);
state *tmp;
while((tmp=DeQueue())!=NULL)
{
ExpandTree(tmp);
}
return 0;
}
![](https://img-my.csdn.net/uploads/201211/20/1353419948_8332.jpg)