三个水杯

时间限制: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
原题出自:http://acm.nyist.net/JudgeOnline/problem.php?pid=21 简单的宽度优先搜索,三个水杯之间的相互倒水如下图6种情况:

对于每一次倒水都会引起三个水杯水量状态的改变,这样就可以得到如下的一个解空间树:

代码一:比较容易想到的

 #include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstdlib>
using namespace std; int v1, v2, v3;
bool visit[][][]; //状态是否出现 struct state
{
int a, b, c;
int ceng; //最小步数
}b, e; int BFS()
{
queue<state> q;
while(!q.empty())
q.pop();
q.push(b);
while(!q.empty())
{
state cur = q.front();
q.pop();
visit[cur.a][cur.b][cur.c] = true; if(cur.a == e.a && cur.b == e.b && cur.c == e.c) //找到
return cur.ceng; if(cur.a > && cur.b < v2) //v1->v2
{
state temp = cur;
int tt = min(temp.a, v2 - temp.b);
temp.a -= tt;
temp.b += tt;
if(visit[temp.a][temp.b][temp.c] == false)
{
visit[temp.a][temp.b][temp.c] = true;
temp.ceng++;
q.push(temp);
}
} if(cur.a > && cur.c < v3) //v1->v3
{
state temp = cur;
int tt = min(temp.a, v3 - temp.c);
temp.a -= tt;
temp.c += tt;
if(visit[temp.a][temp.b][temp.c] == false)
{
visit[temp.a][temp.b][temp.c] = true;
temp.ceng++;
q.push(temp);
}
} if(cur.b > && cur.a < v1) //v2->v1
{
state temp = cur;
int tt = min(temp.b, v1 - temp.a);
temp.a += tt;
temp.b -= tt;
if(visit[temp.a][temp.b][temp.c] == false)
{
visit[temp.a][temp.b][temp.c] = true;
temp.ceng++;
q.push(temp);
}
} if(cur.b > && cur.c < v3) //v2->v3
{
state temp = cur;
int tt = min(temp.b, v3 - temp.c);
temp.b -= tt;
temp.c += tt;
if(visit[temp.a][temp.b][temp.c] == false)
{
visit[temp.a][temp.b][temp.c] = true;
temp.ceng++;
q.push(temp);
}
} if(cur.c > && cur.a < v1) //v3->v1
{
state temp = cur;
int tt = min(temp.c, v1 - temp.a);
temp.c -= tt;
temp.a += tt;
if(visit[temp.a][temp.b][temp.c] == false)
{
visit[temp.a][temp.b][temp.c] = true;
temp.ceng++;
q.push(temp);
}
} if(cur.c > && cur.b < v2) //v3->v2
{
state temp = cur;
int tt = min(temp.c, v2 - temp.b);
temp.c -= tt;
temp.b += tt;
if(visit[temp.a][temp.b][temp.c] == false)
{
visit[temp.a][temp.b][temp.c] = true;
temp.ceng++;
q.push(temp);
}
}
}
return -; //没有终状态
} int main()
{
int n;
scanf("%d", &n);
while(n--)
{
memset(visit, false, sizeof(visit));
scanf("%d %d %d", &v1, &v2, &v3);
b.a = v1, b.b = , b.c = , b.ceng = ;
scanf("%d %d %d", &e.a, &e.b, &e.c);
if(v1 < e.a + e.b + e.c)
{
printf("-1\n");
continue;
}
else
printf("%d\n", BFS());
}
return ;
}

方法二:Floyd 算法

Floyd 算法介绍:http://www.cnblogs.com/orange1438/p/4054649.html

 #include <cstdio>
#include <memory.h>
#include <queue> using namespace std; #define EMPTY 0 struct data_type
{
int state[];
int step;
}; int cupCapacity[], targetState[]; bool visited[][][]; bool AchieveTargetState(data_type current)
{
for (int i = ; i < ; i++)
{
if (current.state[i] != targetState[i])
{
return false;
}
}
return true;
} void PourWater(int destination, int source, data_type &cup)
{
int waterYield = cupCapacity[destination] - cup.state[destination];
if (cup.state[source] >= waterYield)
{
cup.state[destination] += waterYield;
cup.state[source] -= waterYield;
}
else
{
cup.state[destination] += cup.state[source];
cup.state[source] = ;
}
} int BFS(void)
{
int i, j, k;
data_type initial;
queue<data_type> toExpandState; memset(visited, false, sizeof(visited));
initial.state[] = cupCapacity[];
initial.state[] = initial.state[] = ;
initial.step = ;
toExpandState.push(initial);
visited[initial.state[]][][] = true; while (!toExpandState.empty())
{
data_type node = toExpandState.front();
toExpandState.pop();
if (AchieveTargetState(node))
{
return node.step;
}
for (i = ; i < ; i++)
{
for (j = ; j < ; j++)
{
k = (i+j)%;
if (node.state[i] != EMPTY && node.state[k] < cupCapacity[k])
{
data_type newNode = node;
PourWater(k, i, newNode);
newNode.step = node.step + ;
if (!visited[newNode.state[]][newNode.state[]][newNode.state[]])
{
visited[newNode.state[]][newNode.state[]][newNode.state[]] = true;
toExpandState.push(newNode);
}
}
}
}
}
return -;
} int main(void)
{
int testNum;
scanf("%d", &testNum);
while (testNum -- != )
{
scanf("%d%d%d", &cupCapacity[], &cupCapacity[], &cupCapacity[]);
scanf("%d%d%d", &targetState[], &targetState[], &targetState[]);
printf("%d\n", BFS());
}
return ;
}

部分转自:http://blog.csdn.net/code_pang/article/details/7802944

NYOJ 21 三个水杯的更多相关文章

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

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

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

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

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

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

  4. nyoj 题目21 三个水杯

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

  5. nyoj三个水杯(bfs)

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

  6. nyoj 三个水杯

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

  7. 三个水杯 (bfs)

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

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

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

  9. 三个水杯(BFS)

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

随机推荐

  1. ThreadPoolExecutor

    ThreadPoolExecutor机制 一.概述 1.ThreadPoolExecutor作为java.util.concurrent包对外提供基础实现,以内部线程池的形式对外提供管理任务执行,线程 ...

  2. [Z] 北大一牛人生物转申CS的经历

    http://www.bdwm.net/bbs/bbscon.php?board=CIS&file=M.1367038121.A&num=626&attach=0&di ...

  3. 查询修改linux 打开文件句柄数量

    查询系统支持最大可打开文件句柄数量: #vi /proc/sys/fs/file-max 查询当前连接用户最大可打开文件句柄数量: #ulimit -a 修改当前连接用户最大可打开文件句柄数量: #u ...

  4. php 5.4 5.5 如何连接 ms sqlserver

    https://msdn.microsoft.com/en-us/sqlserver/ff657782.aspx

  5. Go语言实现HashSet

    set.go // set project set.go package set type Set interface { Add(e interface{}) bool Remove(e inter ...

  6. Django数据模型及操作

    转自:http://blog.sina.com.cn/s/blog_a73687bc0101cygy.html (一) 初始化测试运行环境 import os; import sys; sys.pat ...

  7. [转]javascript的urlencode

    今天在一个原来使用AJAX自动缩小选择内容的项目上突然发现当输入名称时,如果输入有特殊字符&的时候,选择的内容不会发生变化,也就是说输入的内容在&后面的内容会被截断,经过查证才发现在客 ...

  8. MyBatis知多少(12)私有数据库

    如果你从事软件开发工作有了一段时间的话,那么肯定听过关于“自己动手还是花钱购买” 的争论.该争论是说,针对一个业务问题,我们是应该自己动手构建自己的解决方案呢,还是应 该花钱购买一个声称已经解决了此问 ...

  9. vs2010设置

    解决方案管理器文件自动定位:工具--选项--项目和解决方案--常规--在解决方案资源管理器中跟踪活动项(前打勾). VAssistX拼写错误的下划波浪线去掉:在VAssistX菜单栏->Visu ...

  10. 你或许不了解的C++函数调用(1)

    这篇博客名字起得可能太自大了,搞得自己像C++大牛一样,其实并非如此.C++有很多隐藏在语法之下的特性,使得用户可以在不是特别了解的情况下简单使用,这是非常好的一件事情.但是有时我们可能会突然间发现一 ...