HDU 1495 非常可乐

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1495

大意:有三个杯子,开始时第一个杯子装满水(体积为a)。。。。倒来倒去,得到其中2个杯里的水的体积都为

a/2。。。。求最小次数。。。。不存在就输出NO。。。。

从图(以前都是图题)的点转化成状态(这题比较现实化)。。。。

struct point//a,b,c是某一状态下三个杯里装的水的体积。。。。v是从开始到该状态倒了多少次。。。。

{

  int a, b, c, v;

};

在任意状态下(即每次的队头)。。。。都有6种倒法(即遍历6种)a->b,c。。。

b->a,c。。。。c->a,b。。。。。

#include <iostream>
#include <cmath>
#include <queue>
using namespace std;

const int INF = 1<<30;

bool vis[111][111][111];

struct point
{
int a, b, c, v;
};


void Bfs(int a, int b, int c)
{
point q1, q2;
queue <point> q;
q1.a = a;
q1.b = 0;//初始状态是0,而不是b
q1.c = 0;
q1.v = 0;
q.push(q1);
memset(vis, 0, sizeof(vis));


while (!q.empty())
{
q2 = q.front();
q.pop();
vis[q2.a][q2.b][q2.c] = 1;

//有2个等于a/2就结束
if ((q2.a == a/2 && q2.b == a/2) ||(q2.a == a/2 && q2.c == a/2) ||(q2.b == a/2 && q2.c == a/2))
{
printf("%d\n", q2.v);
return ;
}

//a到其他
if (q2.a != 0)
{
//a->b
if (q2.a > b - q2.b)//倒不完
{
q1.a = q2.a - (b-q2.b);
q1.b = b;
q1.c = q2.c;
q1.v = q2.v + 1;

}
else//倒完
{

q1.b = q2.b + q2.a;//后面是q2.a而不是q1.a
q1.a = 0;
q1.c = q2.c;
q1.v = q2.v + 1;
}
if (!vis[q1.a][q1.b][q1.c])
{
q.push(q1);
vis[q1.a][q1.b][q1.c] = 1;
}


//a->c
if (q2.a > c - q2.c)//倒不完///b
{
q1.a = q2.a - (c-q2.c);
q1.c = c;
q1.b = q2.b;
q1.v = q2.v + 1;
}
else//倒完
{

q1.c = q2.c + q2.a;
q1.a = 0;
q1.b = q2.b;
q1.v = q2.v + 1;
}
if (!vis[q1.a][q1.b][q1.c])
{
q.push(q1);
vis[q1.a][q1.b][q1.c] = 1;
}


}

//b到其他
if (q2.b != 0)
{
//b->a
if (q2.b > a - q2.a)//倒不完
{
q1.b = q2.b - (a-q2.a);
q1.a = a;
q1.c = q2.c;
q1.v = q2.v + 1;

}
else//倒完
{

q1.a = q2.a + q2.b;
q1.b = 0;
q1.c = q2.c;
q1.v = q2.v + 1;
}
if (!vis[q1.a][q1.b][q1.c])
{
q.push(q1);
vis[q1.a][q1.b][q1.c] = 1;
}

//b->c
if (q2.b > c - q2.c)//倒不完//a
{
q1.b = q2.b - (c-q2.c);
q1.c = c;
q1.a = q2.a;
q1.v = q2.v + 1;

}
else//倒完
{

q1.c = q2.c + q2.b;
q1.b = 0;
q1.a = q2.a;
q1.v = q2.v + 1;

}
if (!vis[q1.a][q1.b][q1.c])
{
q.push(q1);
vis[q1.a][q1.b][q1.c] = 1;
}
}

//c到其他
if (q2.c != 0)
{
//c->b
if (q2.c > b - q2.b)//倒不完
{
q1.c = q2.c - (b-q2.b);
q1.b = b;
q1.a = q2.a;
q1.v = q2.v + 1;
if (!vis[q1.a][q1.b][q1.c])
{
q.push(q1);
vis[q1.a][q1.b][q1.c] = 1;
}
}
else//倒完
{

q1.b = q2.b + q2.c;
q1.c = 0;
q1.a = q2.a;
q1.v = q2.v + 1;
if (!vis[q1.a][q1.b][q1.c])
{
q.push(q1);
vis[q1.a][q1.b][q1.c] = 1;
}
}

//c->a
if (q2.c > a - q2.a)//倒不完
{
q1.c = q2.c - (a-q2.a);
q1.a = a;
q1.b = q2.b;
q1.v = q2.v + 1;
if (!vis[q1.a][q1.b][q1.c])
{
q.push(q1);
vis[q1.a][q1.b][q1.c] = 1;
}
}
else//倒完
{

q1.a = q2.a + q2.c;
q1.c = 0;
q1.b = q2.b;
q1.v = q2.v + 1;
if (!vis[q1.a][q1.b][q1.c])
{
q.push(q1);
vis[q1.a][q1.b][q1.c] = 1;
}
}
}

}
puts("NO");
return ;
}

int main()
{
int t;
int n;
int i, j;
int a, b, c;
while (scanf("%d%d%d", &a, &b, &c), a+b+c)
{
if (a % 2 == 1)//剪枝
{
puts("NO");
}
else
{
Bfs(a, b, c);
}
}
return 0;
}
原文地址:https://www.cnblogs.com/qiufeihai/p/2431998.html