分油问题

来源:互联网 发布:linux tcp.h 编辑:程序博客网 时间:2024/05/17 02:25

已知桶、罐和瓶分别能才盛油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;}


原创粉丝点击