分油问题

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


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值