c++ 宽搜(倒水)

题目描述

有一个很大的水缸和二个容量分别为X和Y的水壶,按照以下的规则倒水,问最少经几次倒水后,可得到Z升水
规则1:水缸向水壶1倒水,将水壶1装满;
规则2:水缸向水壶2倒水,将水壶2装满;
规则3:水壶1向水缸倒水,直到水壶1空;
规则4:水壶2向水缸倒水,直到水壶2空;
规则5:水壶1向水壶2倒水,直到水壶1空了或者水壶2满了;
规则6:水壶2向水壶1倒水,直到水壶2空了或者水壶1满了;

输入

只有一行数据,包括以空格分隔的三个数字,分别表示水壶1( <= 100)、 水壶2的水量( <= 100 )以及期望得到的水量( <=100 )。

输出

若经若干次倒水能得到所要求的水量,则输出最少的倒水次数;若无论如何倒水都无法得到规定的水量,则输出No Solution!

样例输入

4 3 1

样例输出

2

AC代码

#include <iostream>
#include <string.h>
using namespace std;
struct point //结构体
{
    int x, y, step;
};
bool used[101][101];
point q[20000], s;
int xx, yy, t;
int f = 1, e = 1;
point gen(point u, int cc)//尝试枚举每一个规则
{
     point v = u;
     v.step = u.step + 1;
     //开始枚举规则
     if (cc == 1) v.x = xx;//水缸向水壶1倒水,将水壶1装满
     else if (cc == 2) v.y = yy;//水缸向水壶2倒水,将水壶2装满
     else if (cc == 3) v.x = 0;//水壶1向水缸倒水,直到水壶1空
     else if (cc == 4) v.y = 0;//水壶2向水缸倒水,直到水壶2空
     else if (cc == 5)//水壶1向水壶2倒水,直到水壶1空了或者水壶2满了
     {
         if (u.x + u.y <= yy) v.x = 0, v.y = u.x + u.y;//如果y能把x和y的水量都装下
         else v.y = yy, v.x = u.x + u.y - yy;//y装不下从x倒过来的水
     }
     else//水壶2向水壶1倒水,直到水壶2空了或者水壶1满了
     {
         if (u.x + u.y <= xx) v.y = 0, v.x = u.x + u.y;//如果x能把x和y的水量都装下
         else v.x = xx, v.y = u.x + u.y - xx;//x装不下从y倒过来的水
     }
     return v;
}
int main()
{
     scanf ("%d %d %d", &xx, &yy, &t);//xx是x桶的水量,yy是y桶的水量
     if (t == 0)
     {
         printf ("0\n");
         return 0;
     }
     memset (used, 0, sizeof (used));//memset
     s.x = 0, s.y = 0, s.step = 0;
     q[1] = s;
///开始宽搜///
     while (f <= e)//f是出队下标  e是入队下标
     {
         point u = q[f++];//选定的元素
         for (int i = 1; i <= 6; i++)//尝试枚举6个规则
         {
             point v = gen(u, i);//v就是将要入队的元素
             if (used[v.x][v.y] == 0)
             {
                 if (v.x == t || v.y == t)//任意一个杯子里面有目标水量
                 {
                     printf ("%d\n", v.step);//就打印步数
                     return 0;//默默退出
                 }
                 q[++e] = v;//入队
                 used[v.x][v.y] = 1;//表示已经被选择过
             }
         }
     }
     printf ("No Solution!\n");//如果无法完成
     return 0;
}

思路分析

step1:将初始状态入队
step2:以初始状态为中心按6个规则向6个方向寻找可能的值入队
step3:在通过可能的值向6个方向继续拓展,直到找到目标(水壶1 或 水壶2 中的水 等于目标水量)

转载于:https://www.cnblogs.com/LJA001162/p/11218432.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉树的度优先索(BFS)是一种遍历二叉树的方法。BFS 从二叉树的根节点开始,逐层访每个节点,直到遍历完整棵树。在 BFS 中,我们使用一个队列来存储要访的节点。下面是一个 C++ 实现的例子: ```c++ #include <iostream> #include <queue> using namespace std; // 二叉树节点结构体 struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; void bfs(TreeNode* root) { if (!root) return; queue<TreeNode*> q; q.push(root); while (!q.empty()) { int size = q.size(); for (int i = 0; i < size; i++) { TreeNode* node = q.front(); q.pop(); cout << node->val << " "; if (node->left) q.push(node->left); if (node->right) q.push(node->right); } cout << endl; } } int main() { // 创建二叉树 TreeNode* root = new TreeNode(1); root->left = new TreeNode(2); root->right = new TreeNode(3); root->left->left = new TreeNode(4); root->left->right = new TreeNode(5); // 遍历二叉树 bfs(root); return 0; } ``` 在上面的例子中,我们使用了一个队列 q 来存储要访的节点。首先,我们将根节点 root 入队。然后,我们进入一个 while 循环,直到队列 q 为空。在每次循环中,我们获取队列 q 的长度 size,并依次访队列中的前 size 个节点。对于每个节点,我们都先输出它的值,然后将它的左右子节点加入队列 q 中。这样,就可以逐层访整个二叉树了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值