题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=21
描述
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
输入
第一行一个整数N(0< N<50)表示N组测试数据
接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的体积。
第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们需要的最终状态
输出
每行输出相应测试数据最少的倒水次数。如果达不到目标状态输出-1
样例输入
2
6 3 1
4 1 1
9 3 2
7 1 1
样例输出
3
-1
题目 刚开始 没理解 意思 , 看着测试数据 觉得 这不是 随便一到 不就 好了么。
看了 好久 才发现 自己题意都理解错了
这道题 确实 是倒水 但要 根据 被倒水的杯子容量和倒水的杯子的水量决定
举个栗子 :
a—–>b
如果 a中水 比 b的剩余容量多 那么 a到将b倒满 a中水 就变为减去给b的量 (被倒的杯子 尽量 被倒满)
如果a中水 比b的剩余容量少 那么 a中水 全部 给b a变为0
!!!! 当然 在 倒水前 先要判断是否需要倒水 —-》a中必须有水,且 b不能满
还有 标记 数组vist 是个 3维的 只是用来表示 每种3种杯子 在某种状态下 是否 访问过 避免 重复判断。
那么 这道题 就很容易了 用 bfs 即可
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int vist[101][101][101]; //标记状态 ,判断是否 访问.
//vist[1][2][3]==1;代表 当三个杯子水分别为1,2,3时是访问过
int v[3],e[3];
struct node
{
int state[3]; //3个杯子的状态
int step; //步数
};
int isend(node now) //判断是否满足结束条件
{
for (int i=0; i<3; i++)
{
if (now.state[i]!=e[i])
return 0;
}
return 1;
}
void pullwater(int i,int k, node & now) //进行倒水操作 记得用 & (在这栽了)
{
int cz = v[k] - now.state[k];
if (now.state[i]<cz)
{
now.state[k] += now.state[i];
now.state[i] = 0;
}
else
{
now.state[k] += cz;
now.state[i] -= cz;
}
}
int bfs()
{
int i,j,k;
queue<node> q;
node now,next;
now.state[0] = v[0]; //赋初始状态
now.state[1] = now.state[2] = 0;
now.step = 0;
q.push(now);
vist[now.state[0]][now.state[1]][now.state[2]]=1; //标记状态已访问
while (!q.empty())
{
now = q.front();
q.pop();
if (isend(now))
return now.step;
for (i=0;i<3;i++)
{
for (j=1; j<3; j++)
{
k = (i+j)%3;
if (now.state[i]!=0&&now.state[k]<v[k])
{
next = now;
pullwater(i,k,next);
next.step = now.step+1;
// cout<<next.state[0]<<" "<<next.state[1]<<" "<<next.state[2]<<endl;
if (vist[next.state[0]][next.state[1]][next.state[2]]==0) //下一状态没有访问,标记进队
{
vist[next.state[0]][next.state[1]][next.state[2]]=1;
q.push(next);
}
}
}
}
}
return -1;
}
int main()
{
int N;
cin>>N;
while (N--)
{
cin>>v[0]>>v[1]>>v[2];
cin>>e[0]>>e[1]>>e[2];
memset(vist,0,sizeof(vist));
int ans = bfs();
cout<<ans<<endl;
}
return 0;
}