描述
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
-
输入
-
第一行一个整数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
-
-
-
-
-
这是关于广搜的一道题目 代码也只是勉强看懂 希望能给那些和我一样的入门者提供一些思路
-
- #include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
struct node
{
int a,b,c,step;//a,b,c 表示水杯中水的体积 为变量 step为变量,记录倒水的次数
};
int v1,v2,v3,v11,v22,v33;
bool vis[101][101][101]; //标记情况有没有出现 三维数组
void init()
{
scanf("%d%d%d%d%d%d",&v1,&v2,&v3,&v11,&v22,&v33);//输入水杯的容量和要达到的状态
}
void bfs()
{
bool flag=false;
memset(vis,false,sizeof(vis));
queue<node> que; //建立一个队列
que.push(node{v1,0,0,0}); //初始化队列的状态 即第一个杯子(最大的杯子)是装满的
node n;//建立了一个结构体变量
int t;
while(!que.empty())//如果 que.empty() 等于0 que.empty 队列是否为空的判断条件 此处的意思为 如果队列不是空队列
{
n=que.front(); //n等于队列的对头元素
que.pop();//队首元素出队
if(n.a==v11 && n.b==v22 && n.c==v33)//判断水杯中的水是否是想达到的状态
{
flag=true;
break;
}
if(vis[n.a][n.b][n.c]) continue;//如果 vis[n.a][n.b][n.c] ==0 跳过 不予考虑
vis[n.a][n.b][n.c]=true;
t=(n.a>=v2-n.b)? v2-n.b:n.a; // t总是取两个之间较小的一个。 v2-n.b表示现状态与目标状态的差距
que.push(node{n.a-t,n.b+t,n.c,n.step+1});//倒水 从a中往b中倒水,将b装满。step+1
t=(n.a>=v3-n.c)? v3-n.c:n.a;
que.push(node{n.a-t,n.b,n.c+t,n.step+1});
t=(n.b>=v1-n.a)? v1-n.a:n.b;
que.push(node{n.a+t,n.b-t,n.c,n.step+1});
t=(n.b>=v3-n.c)? v3-n.c:n.b;
que.push(node{n.a,n.b-t,n.c+t,n.step+1});
t=(n.c>=v1-n.a)? v1-n.a:n.c;
que.push(node{n.a+t,n.b,n.c-t,n.step+1});
t=(n.c>=v2-n.b)? v2-n.b:n.c;
que.push(node{n.a,n.b+t,n.c-t,n.step+1});//此六句构成一个循环 每次三个水杯内的水都会改变 直到到达目的状态为止
}
if(flag) printf("%d\n",n.step);
else printf("-1\n");
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
init();
bfs();
}
return 0;
}
下面的代码不是用队列
01.
#include <iostream>
02.
#include <cmath>
03.
#include <algorithm>
04.
#include <cstring>
05.
#include <cstdio>
06.
using
namespace
std;
07.
int
a[100];
08.
int
b[100];
09.
int
v[100];
10.
int
d[100][100][100];
11.
int
minn;
12.
void
fun(
int
k)
13.
{
14.
int
i;
15.
//for(i=0;i<3;i++) cout<<v[i]<<' '; cout<<' '<<k<<endl;
16.
for
(i=0;i<3;i++)
17.
{
18.
if
(v[i]!=b[i])
break
;
19.
}
20.
if
(i==3)
21.
{
22.
if
(minn>k)
23.
minn=k;
24.
return
;
25.
//cout<<k<<endl;
26.
}
27.
for
(i=0;i<3;i++)
28.
{
29.
for
(
int
j=0;j<3;j++)
30.
{
31.
if
(j==i)
continue
;
32.
if
(v[j]<a[j])
33.
{
34.
int
p;
35.
int
c[100];
36.
for
(
int
t=0;t<3;t++)
37.
c[t]=v[t];
38.
if
(v[i]-(a[j]-v[j])>=0)
39.
{
40.
v[i]=v[i]-(a[j]-v[j]);
41.
p=a[j]-v[j];
42.
}
43.
else
44.
{
45.
p=v[i];
46.
v[i]=0;
47.
}
48.
v[j]+=p;
49.
50.
if
(d[v[0]][v[1]][v[2]]>k)
51.
{
52.
d[v[0]][v[1]][v[2]]=k;
53.
fun(k+1);
54.
}
55.
for
(
int
t=0;t<3;t++)
56.
v[t]=c[t];
57.
}
58.
}
59.
}
60.
}
61.
int
main()
62.
{
63.
int
t;
64.
cin>>t;
65.
while
(t--)
66.
{
67.
memset
(v,0,
sizeof
(v));
68.
memset
(d,1000000,
sizeof
(d));
69.
int
i;
70.
minn=10000000;
71.
for
(i=0;i<3;i++)
72.
cin>>a[i];
73.
for
(i=0;i<3;i++)
74.
cin>>b[i];
75.
v[0]=a[0];
76.
fun(0);
77.
if
(minn!=10000000) cout<<minn<<endl;
78.
else
cout<<
"-1"
<<endl;
79.
}
80.
return
0;
81.
}