其他分享
首页 > 其他分享> > 倒水问题

倒水问题

作者:互联网

倒水问题

题目:两个容量不同且互质的杯子相互倒水(相互倒水时必须将其中一个杯子倒水或者倒空,不存在倒半杯的情况,要不然谁也不能确定倒了多少升水不是),直到倒出C升的水。
题目详细描述如下:

在这里插入图片描述
思路
本道题主要考察bfs,就是从水量(0,0)的时候一直倒水至(C,x)或者(x,C),x为未知量。为了不重复之前的倒水步骤(即陷入死循环),必须对每一个到达过的水量进行标记。然后将六种倒水状态分别编辑成一个函数,例如“empty A”就是将A中的水倒空,B中水量不变。在进行每一层bfs的时候,依次执行六个操作(fill A/fill B/empty A/empty B/pour A to B/po),直到倒出C升的水。为了在倒完水之后回溯整个倒水过程,需要记录下每一次倒水之前的水量与倒水之后的水量。

函数解释与方法选择
1.首先进行bfs所以选择了队列,不再具体说明。
2.选择使用pair记录了每一次的水量。
3.选择map记录每次倒水前与倒水后杯中的水量(key:倒水前,value:倒水后),这样便很容易用from[倒水后]的方法回溯倒水过程,同时还可以判断当前倒水状态是否已存在(使用find函数)。
4.check函数检查该倒水状态是否存在,若不存在将当前倒水状态加入map。
5.print3函数,通过递归输出倒水的过程。
6.judge4函数,根据回溯的杯中水量判断进行的是六种倒水操作的哪一种。

说明:
写了好几版print和judge函数,功能一样,具体实现有所不同,最后采用的是print3和judge4!!!!(因为不愿意发生删除删错了的悲剧…就不删了)

激动人心的代码:

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

map<pair<int, int>, pair<int, int> > from;//to,from
queue<pair<int, int> > q;
int A, B, C;//容量 
int x[1000];

pair<int, int> AtoB(pair<int, int> &p)
{
     pair<int, int> p1;
     p1.first = max(0, p.first + p.second - B);
     p1.second = min(B, p.first + p.second);
     return p1;
}

pair<int, int> BtoA(pair<int, int> &p)
{
     pair<int, int> p1;
     p1.first = min(A, p.first + p.second);
     p1.second = max(0, p.first + p.second - A);
     return p1;
}

pair<int, int> emptyA(pair<int, int> &p)
{
     pair<int, int> p1(0, p.second);
     return p1;
}

pair<int, int> emptyB(pair<int, int> &p)
{
     pair<int, int> p1(p.first, 0);
     return p1;
}

pair<int, int> fillA(pair<int, int> &p)
{
     pair<int, int> p1(A, p.second);
     return p1;
}

pair<int, int> fillB(pair<int, int> &p)
{
     pair<int, int> p1(p.first, B);
     return p1;
}


void check(pair<int, int> &f, pair<int, int> &t)
{
     if (from.find(t) == from.end())//没有经历过这种情况
     {
          from[t] = f;
          q.push(t);
     }
}

void bfs()
{
     pair<int, int> p1(0, 0);
     q.push(p1);
     from[p1] = p1;
     int a, b;
     while (!q.empty())
     {
         memset(x, 0, sizeof x);
         pair<int, int> f = q.front();
         q.pop();
  
         pair<int, int> f1 = fillA(f);
         check(f, f1);

         pair<int, int> f2 = fillB(f);
         check(f, f2);

         pair<int, int> f3 = emptyA(f);
         check(f, f3);
  
         pair<int, int> f4 = emptyB(f);
         check(f, f4);

         pair<int, int> f5 = BtoA(f);
         check(f, f5);
  
         pair<int, int> f6 = AtoB(f);
         check(f, f6);
  
         if (f.first == C || f.second == C)
         {
             a = f.first;
             b = f.second;
             break;
         }
     }
     pair<int, int> result(a, b);
     print3(result);
     cout << "success" << endl;
}



int main()
{
     while (cin >> A >> B >> C)
     {
          bfs();
          from.clear();
           while (!q.empty()) q.pop();
     }
     return 0;
}
溢熙 发布了1 篇原创文章 · 获赞 0 · 访问量 29 私信 关注

标签:倒水,p1,问题,second,pair,check,first
来源: https://blog.csdn.net/weixin_44876049/article/details/104611619