三个水杯 
时间限制:1000 ms | 内存限制:65535 KB 
难度:4

描述 
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。

输入 
第一行一个整数N(0<N<50)N(0<N<50)表示N组测试数据 
接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3V1<100V3>0)(V1>V2>V3V1<100V3>0)表示三个水杯的体积。 
第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们需要的最终状态 
输出 
每行输出相应测试数据最少的倒水次数。如果达不到目标状态输出-1 
样例输入

2

6 3 1

4 1 1

9 3 2

7 1 1

样例输出

3

-1

第一次做广搜,参考别人的写的。用广搜的原因是每个杯子只能向其他两个杯子倒水,不能像自己倒水,就像树一样,走根节点走向子节点。

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

int v[4],e[4];
bool visit[101][101][101];//用于剪枝,visited[2][3][4]=true用来标记第1个杯子装2单位水,
//第2个杯子装3单位水,第3个杯子装4单位水已经访问过,
//以后遇到这种情况不用入队列了
typedef struct
{
int state[4];//用来保存三个杯子中的水的状态——state[1]的值代表第一个水杯的状态 ...
int setp;
}N;
//第i个杯子向第k个杯子倒水
void pour_Water(int i,int k,N& n)
{
if(n.state[i]<=v[k]-n.state[k])//如果第i个杯子中水的量小于k杯子的目标容量减去k杯子中现在的水量
{
n.state[k]+=n.state[i];
n.state[i]=0;
}
else
{
n.state[i]-=(v[k]-n.state[k]);
n.state[k]=v[k];
}
}

void BFS()
{
queue<N> q;
N start,next;
memset(visit,false,sizeof(visit));//标记每种状态的情况都没出现过
//初始化刚开始的状态,就是把第一个杯子得水装满,其余两个杯子不装水
start.setp=0;
start.state[1]=v[1];
start.state[2]=start.state[3]=0;
visit[start.state[1]][start.state[2]][start.state[3]]=true;
q.push(start);

while(!q.empty())
{
//如果满足目标状态,就可以退出。
if(next.state[1]==e[1]&&next.state[2]==e[2]&&next.state[3]==e[3])
{
cout<<next.setp<<endl;
return ;
}

next=q.front();//把队头元素取出来
q.pop();
N temp;
for(int i=0;i<3;i++)
for(int j=1;j<3;j++)//相当于以某个节点为根节点按层遍历,即bfs
{
//此式子可以保证当i+1为1时,k+1取2,3
//i+1=2时,k+1=1,3;i+1=3时,k+1=1,2
int k=(i+j)%3;
temp=next;//next杯子倒水,结果储存在temp中 ,
pour_Water(i+1,k+1,temp);
temp.setp+=1;
//如果此时三个杯中的水的状态没有出现过,把这种状态入队
if(!visit[temp.state[1]][temp.state[2]][temp.state[3]])
{
visit[temp.state[1]][temp.state[2]][temp.state[3]]=true;
q.push(temp);
}
}
}
//所有水杯的状态都进过队且没有一个满足目标状态的,
cout<<"-1"<<endl;
return ;
}

int main()
{
int n;
cin>>n;
while(n--)
{
cin>>v[1]>>v[2]>>v[3];
cin>>e[1]>>e[2]>>e[3];
BFS();
}
return 0;
}

nyoj 三个水杯的更多相关文章

  1. nyoj三个水杯(bfs)

    三个水杯 时间限制:1000 ms  |           内存限制:65535 KB 难度:4   描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互 ...

  2. NYOJ 21 三个水杯

    三个水杯 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有 ...

  3. nyoj 21三个水杯(BFS + 栈)

    题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=21 思想: 看了一下搜索就来写了这题(BFS 找出最短路径 所以用此来进行搜索) 这题在 ...

  4. nyoj 题目21 三个水杯

    三个水杯 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有 ...

  5. NYOJ 21.三个水杯-初始态到目标态的最少次数-经典BFS

    题目传送门:biubiubiu~ 三个水杯 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子. ...

  6. NYOJ #21 三个水杯(bfs)

    描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算.现在要求你写出一个程序,使其输出使初始状态到达目标 ...

  7. 三个水杯 (bfs)

    给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算.现在要求你写出一个程序,使其输出使初始状态到达目标状态的 ...

  8. 三个水杯——java,广度优先搜索

    题目如下: 21-三个水杯 内存限制:64MB 时间限制:1000ms 特判: No通过数:51 提交数:137 难度:4 题目描述: 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个 ...

  9. nyoj 21--三个水杯(隐式图bfs)

    三个水杯 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识 ...

随机推荐

  1. ubuntu谷歌浏览器安装

    sudo apt-get install  chromium-browser-dbg 然后按照规定就好了.

  2. TCP文件发送

    发送端(客户端) #include <iostream> #include <winsock2.h> #include <Ws2tcpip.h> #include ...

  3. cf-789A (思维)

    A. Anastasia and pebbles time limit per test 1 second memory limit per test 256 megabytes input stan ...

  4. Java容器涉及的类(代码)

    Customer: public class Customer implements Comparable{ private Integer customerId; private String cu ...

  5. 43. Multiply Strings 字符串表示的大数乘法

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

  6. 使用GAN进行异常检测——可以进行网络流量的自学习哇,哥哥,人家是半监督,无监督的话,还是要VAE,SAE。

    实验了效果,下面的还是图像的异常检测居多. https://github.com/LeeDoYup/AnoGAN https://github.com/tkwoo/anogan-keras 看了下,本 ...

  7. 管道的创建与读写pipe

    1.管道的创建 #include <unistd.h> int pipe(int pipefd[2]); linux下创建管道可以通过函数pipe来完成.该函数如果调用成功,数组中将包含两 ...

  8. Android如何打印std::cout/printf(重定向stdout)

    Android应用调试时没有stdout和stderr的输出,网上看到的解释都是下面这个样子: ################################################# An ...

  9. 跟我一起学习ASP.NET 4.5 MVC4.0(四)

    前几个文章中介绍了一些关于MVC4.0的东东,今天我们来看一下登陆验证,也可以说是权限验证,即AuthorizeAttribute.这个可以使用在控制器Controller上,也可以使用在Action ...

  10. 使用array_merge重新排列数组下标

    array_merge() 函数把两个或多个数组合并为一个数组. 如果键名有重复,该键的键值为最后一个键名对应的值(后面的覆盖前面的).如果数组是数字索引的,则键名会以连续方式重新索引. 注释:如果仅 ...