三个水杯
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
-
输入
-
第一行一个整数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
BFS
01.
#include <iostream>
02.
#include <queue>
03.
#include <string.h>
04.
using
namespace
std;
05.
06.
struct
node
07.
{
08.
int
sta[3];
09.
int
step;
10.
};
11.
12.
int
visit[100][100][100];
13.
int
v[3],e[3];
14.
queue<node> qu;
15.
16.
int
check(node x)
17.
{
18.
if
(x.sta[0]==e[0]&&x.sta[1]==e[1]&&x.sta[2]==e[2])
19.
return
1;
20.
else
21.
return
0;
22.
}
23.
24.
int
bfs(
int
x,
int
y,
int
z)
25.
{
26.
node t;
27.
t.sta[0]=x;
28.
t.sta[1]=y;
29.
t.sta[2]=z;
30.
t.step=0;
31.
qu.push(t);
32.
while
(!qu.empty())
33.
{
34.
node t1;
35.
t1=qu.front();
36.
qu.pop();
37.
for
(
int
i=0;i<3;i++)
38.
for
(
int
j=0;j<3;j++)
39.
{
40.
if
(i!=j)
41.
{
42.
if
(t1.sta[i]&&t1.sta[j]!=v[j])
43.
{
44.
node t2;
45.
t2.sta[0]=t1.sta[0];
46.
t2.sta[1]=t1.sta[1];
47.
t2.sta[2]=t1.sta[2];
48.
t2.step=t1.step+1;
49.
if
(t1.sta[i]>=v[j]-t1.sta[j])
50.
{
51.
t2.sta[i]=t1.sta[i]-(v[j]-t1.sta[j]);
52.
t2.sta[j]=v[j];
53.
}
54.
else
55.
{
56.
t2.sta[i]=0;
57.
t2.sta[j]=t1.sta[i]+t1.sta[j];
58.
}
59.
if
(!visit[t2.sta[0]][t2.sta[1]][t2.sta[2]])
60.
{
61.
if
(check(t2))
62.
return
t2.step;
63.
visit[t2.sta[0]][t2.sta[1]][t2.sta[2]]=1;
64.
qu.push(t2);
65.
}
66.
}
67.
}
68.
}
69.
}
70.
return
-1;
71.
}
72.
int
main()
73.
{
74.
int
n;
75.
cin>>n;
76.
while
(n--)
77.
{
78.
memset
(visit,0,
sizeof
(visit));
79.
cin>>v[0]>>v[1]>>v[2];
80.
cin>>e[0]>>e[1]>>e[2];
81.
if
(e[0]==v[0]&&e[1]==0&&e[2]==0)
82.
{
83.
cout<<
"0"
<<endl;
84.
continue
;
85.
}
86.
visit[v[0]][0][0]=1;
87.
cout<<bfs(v[0],0,0)<<endl;
88.
}
89.
return
0;
90.
}
再贴一个最优的
01.
#include<iostream>
02.
#include<cstdio>
03.
#include<cstring>
04.
#include<algorithm>
05.
#include<bitset>
06.
using
namespace
std;
07.
#define CLR(arr,val) memset(arr,val,sizeof(arr))
08.
bitset<1000000> Hash;
09.
const
int
MAX_STEP=100000;
10.
int
WQ[MAX_STEP][4],Goal[3],Cap[3],goalval;
11.
int
head=0,tail=0;
12.
void
movw(
int
numfrom,
int
numto,
int
other)
13.
{
14.
int
total=WQ[head][numfrom]+WQ[head][numto];
15.
WQ[tail][other]=WQ[head][other];
16.
WQ[tail][3]=WQ[head][3]+1;
17.
if
(total>Cap[numto])
18.
{
19.
WQ[tail][numfrom]=total-Cap[numto];
20.
WQ[tail][numto]=Cap[numto];
21.
}
22.
else
23.
{
24.
WQ[tail][numfrom]=0;
25.
WQ[tail][numto]=total;
26.
}
27.
int
hashval=WQ[tail][0]*10000+WQ[tail][1]*100+WQ[tail][2];
28.
if
(hashval==goalval)
throw
WQ[head][3]+1;
29.
if
(WQ[head][numfrom]!=0 && !Hash[hashval])
30.
{
31.
Hash[hashval]=
true
;
32.
if
(++tail==MAX_STEP) tail=0;
33.
}
34.
}
35.
int
main()
36.
{
37.
int
t;
38.
scanf
(
"%d"
,&t);
39.
while
(t--)
40.
{
41.
Hash.reset();
42.
scanf
(
"%d%d%d%d%d%d"
,&Cap[0],&Cap[1],&Cap[2],&Goal[0],&Goal[1],&Goal[2]);
43.
head=0,tail=0,goalval=Goal[0]*10000+Goal[1]*100+Goal[2];
44.
if
(Goal[1]==0 && Goal[2]==0 && Goal[0]==Cap[0]) {
puts
(
"0"
);
continue
;}
45.
WQ[tail][0]=Cap[0];WQ[tail][1]=0;WQ[tail][2]=0;WQ[tail][3]=0;
46.
++tail;
47.
try
{
48.
while
(head!=tail)
49.
{
50.
movw(0,1,2);movw(1,2,0);movw(0,2,1);movw(1,0,2);movw(2,1,0);movw(2,0,1);
51.
if
(++head==MAX_STEP) head=0;
52.
}
53.
puts
(
"-1"
);
54.
}
catch
(
int
step)
55.
{
56.
printf
(
"%d\n"
,step);
57.
}
58.
}
59.
}
-
第一行一个整数N(0<N<50)表示N组测试数据