每日一题 隐式图 倒水问题

很久没有做题了,慢慢熟悉起来吧!ACM不可间断,唉唉唉唉

有三个无刻度标志的水杯,分别可装 a ,b , c升水,并且a>b , a>c , a,b,c,均为正整数。任意两个水杯之间可以相互倒水。用

 
杯子x给y倒水的时必须一直持续到把杯子y倒满或者把杯子x倒空,而不能中途停止。倒水过程中水量不变。最初的时候只有大杯子
 
装满水,其他两个杯子为空。问能不能量出x升水,如果可以,最少需要多少步?
#include<stdio.h>
#include<string.h>
#define MAXN 4000

int a, b, c, x;
char v[1010][1010];

typedef struct pub
{
	int a,b,c;
	int num;
	pub()
	{
		num = 0;
	}
} pub;

pub d[MAXN];

void bfs()
{
	int front = 0, rear = 1;
	while(rear > front)
	{//printf("111111111111111111111\n");
		if(d[front].a > 0 && d[front].b < b && !v[d[front].a][d[front].b])//a yu b huan
		{
			d[rear].num = d[front].num + 1;
			if(d[front].a > b-d[front].b)
			{
				d[rear].a = d[front].a - (b-d[front].b);
				d[rear].c = d[front].c;
				d[rear++].b = b;
			}
			else
			{
				d[rear].a = 0;
				d[rear].c = d[front].c;
				d[rear++].b = d[front].b + d[front].a; 
			}
			//printf("a=%d b=%d c=%d  \n ",d[rear-1].a,d[rear-1].b,d[rear-1].c);
			if(d[front].a==x || d[front].b==x || d[front].c==x) break;
		}
		if(d[front].a > 0 && d[front].c < c && !v[d[front].a][d[front].b])//a yu c huan
		{
			d[rear].num = d[front].num + 1;
			if(d[front].a > c-d[front].c)
			{
				d[rear].a = d[front].a - (c-d[front].c);
				d[rear].b = d[front].b;
				d[rear++].c = c;
			}
			else
			{
				d[rear].a = 0;
				d[rear].b = d[front].b;
				d[rear++].c = d[front].c + d[front].a; 
			}
			//printf("a=%d b=%d c=%d   \n",d[rear-1].a,d[rear-1].b,d[rear-1].c);
			if(d[front].a==x || d[front].b==x || d[front].c==x) break;
		}
		if(d[front].b > 0 && d[front].a < a && !v[d[front].a][d[front].b])//b yu a huan
		{
			d[rear].num = d[front].num + 1;
			if(d[front].b > a-d[front].a)
			{
				d[rear].b = d[front].b - (a-d[front].a);
				d[rear].c = d[front].c;
 				d[rear++].a = a;
			}
			else
			{
				d[rear].b = 0;
				d[rear].c = d[front].c;
				d[rear++].a = d[front].a + d[front].b; 
			}
		//	printf("a=%d b=%d c=%d  \n ",d[rear-1].a,d[rear-1].b,d[rear-1].c);
			if(d[front].a==x || d[front].b==x || d[front].c==x) break;
		}
		if(d[front].b > 0 && d[front].c < c && !v[d[front].a][d[front].b])//b yu c huan
		{
			d[rear].num = d[front].num + 1;
			if(d[front].b > c-d[front].c)
			{
				d[rear].b = d[front].b - (c-d[front].c);
				d[rear].a = d[front].a;
				d[rear++].c = c;
			}
			else
			{
				d[rear].b = 0;
				d[rear].a = d[front].a;
				d[rear++].c = d[front].c + d[front].b; 
			}
			//printf("a=%d b=%d c=%d   \n",d[rear-1].a,d[rear-1].b,d[rear-1].c);
			if(d[front].a==x || d[front].b==x || d[front].c==x) break;
		}
		if(d[front].c > 0 && d[front].a < a && !v[d[front].a][d[front].b])//c yu a huan
		{
			d[rear].num = d[front].num + 1;
			if(d[front].c > a-d[front].a)
			{
				d[rear].c = d[front].c - (a-d[front].a);
				d[rear].b = d[front].b;
				d[rear++].a = a;
			}
			else
			{
				d[rear].c = 0;
				d[rear].b = d[front].b;
				d[rear++].a = d[front].a + d[front].c; 
			}
			//printf("a=%d b=%d c=%d   \n",d[rear-1].a,d[rear-1].b,d[rear-1].c);
			if(d[front].a==x || d[front].b==x || d[front].c==x) break;
		}
		if(d[front].c > 0 && d[front].b < b && !v[d[front].a][d[front].b])//c yu b huan
		{
			d[rear].num = d[front].num + 1;
			if(d[front].c > b-d[front].b)
			{
				d[rear].c = d[front].c - (b-d[front].b);
				d[rear].a = d[front].a;
				d[rear++].b = b;
			}
			else
			{
				d[rear].c = 0;
				d[rear].a = d[front].a;
				d[rear++].b = d[front].c + d[front].b; 
			}
			//printf("a=%d b=%d c=%d\n",d[rear-1].a,d[rear-1].b,d[rear-1].c);
			if(d[front].a==x || d[front].b==x || d[front].c==x) break;
		}
		v[d[front].a][d[front].b] = 1;
		//printf("hvis=%d\n",front);
		front ++;
		//puts("");
	}
	if(front >= rear) printf("-1\n");	
	else printf("%d\n",d[rear-1].num - 1);
}

void init()
{
	while(~scanf("%d%d%d%d",&a,&b,&c,&x))
	{
		memset(v,0,sizeof(v));
		d[0].a = a;
		d[0].b = 0;
		d[0].c = 0;
		bfs();
	}	
}

int main()
{
	init();
	return 0;
}

  

原文地址:https://www.cnblogs.com/yuzhaoxin/p/2594060.html