描述
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
-
输入
- 第一行一个整数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.else44.{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.}
1261

被折叠的 条评论
为什么被折叠?



