第二周作业 B题

B题 倒水

题目描述:

倒水问题"fill A" 表示倒满A杯,"empty A"表示倒空A杯,“pour A B” 表示把A的水倒到B杯并且把B杯倒满或A倒空

Input

输入包含多组数据。每组数据输入 A, B, C
数据范围 0 < A <= B 、C <= B <=1000 、A和B互质。

Output

你的程序的输出将由一系列的指令组成。这些输出行将导致任何一个罐子正好包含C单位的水。每组数据的最后一行输出应该是“success”。输出行从第1列开始,不应该有空行或任何尾随空格。

Sample Input

2 7 5
2 7 4

Sample Output

fill B
pour B A
success
fill A
pour A B
fill A
pour A B
success

解题思路:这道题有六种不同的操作,:
fill A
fill B
empty A
empty B
pour A B
pour B A
但是我们可以通过前后两次水量的变化情况来判断做了什么操作,例如:A杯水量没变,则如果B杯水量满,则是fill B,如果B杯水量为0 则进行操作empty B,B杯同理,还有就是,A杯变少,则是pour A B,否则是pour B A

那么接下来要进行判断什么时候进行什么操作:用到bfs来找出最少的操作数目
(1)倒空A 杯
(2)倒空B杯
(3)倒满A杯
1.B杯没有为0
①将B导入A却倒不满,B=0 A=A+B
②将B倒满A, A=A满 B=A+B-A满
(4)与(3)同理换成B
直到A或B的水量为C则退出bfs,然后递归输出

#include <iostream>
#include<queue>
#include<map>
using namespace std;
struct Status 
{
 int a,b;
 Status(){}
 Status(int aa,int bb)
 {
  a=aa; b=bb;
 }
 bool operator<(const Status &s) const 
 {
  return a!=s.a ? a<s.a : b<s.b;
 }
};
queue<Status> q;
map<Status, Status> from;//map用来记录a/b杯水的上一状态和当前状态 
int A,B,C;
void print_judge(Status &s,Status &t)
{//通过判断倒水操作的前后状态来判断进行了什么操作 
 if(s.a==t.a)
 {//a杯没变 
  if(t.b==B) //操作之后b杯是满的 
   cout<<"fill B"<<endl;
  else
   cout<<"empty B"<<endl;
 }
 else if(s.b==t.b)
 {//b杯没变 
  if(t.a==A) 
   cout<<"fill A"<<endl;
  else
   cout<<"empty A"<<endl; 
 }
 else{
  if(t.a<s.a) //a杯少了 
   cout<<"pour A B"<<endl;
  else
   cout<<"pour B A"<<endl; 
 }
}
void print(Status &p) 
{
    if ( from.find(p) == from.end() || (p.a == 0&&p.b==0) )
    {
        return;
    }
    print(from[p]); // 递归
    print_judge(from[p],p);
    
}
void refresh(Status &s, Status &t) 
{
    if ( from.find(t) == from.end() ) 
    { // 特判合法,加入队列
        from[t] = s;
        q.push(t);
    }
}
void bfs() 
{
 Status s(0,0);
 Status t;
 q.push(s);
 while (!q.empty()) 
 {
        s = q.front(); 
  q.pop();
        if (s.a == C || s.b == C)
  {
            print(s);
            return;
        }
        if (s.a > 0) 
  {
            t.a = 0; 
            t.b = s.b;
            refresh(s, t);
        }
        if (s.b > 0) {
            t.b = 0; 
            t.a = s.a;
            refresh(s, t);
        }
        if (s.a < A) 
        {
         t.a = A;  
         t.b = s.b;
            refresh(s, t);
            if (s.b != 0) 
            {
                if (s.a + s.b <= A) 
                {
                    t.a = s.a + s.b;
                    t.b = 0;
              refresh(s, t);
                } else 
                {
                    t.a = A;
                    t.b = s.a + s.b - A;
              refresh(s, t);
                }
            }
        }
        if (s.b < B) 
        {
            t.a = s.a;
            t.b = B;
            refresh(s, t);
            if (s.a != 0) 
            {
                if (s.a + s.b <= B) 
                {
                    t.a = 0;
                    t.b = s.a + s.b;
                    refresh(s, t);
                } else 
                {
                    t.a = s.a + s.b - B;
                    t.b = B;
                    refresh(s, t);
                }
            }
        }
    }
}
int main() 
{ 
    while(cin>>A>>B>>C)
    {
     while(!q.empty()){
      q.pop();
  }
  from.clear();
     bfs();
     cout<<"success"<<endl;
 }
    return 0;
}
发布了20 篇原创文章 · 获赞 0 · 访问量 235

猜你喜欢

转载自blog.csdn.net/GuaXX/article/details/104975686