无脑博士的试管们(状态图的深度优先搜索)

无脑博士有三个容量分别是 A,B,CA,B,C 升的试管,A,B,CA,B,C 分别是三个从 11 到 2020 的整数,最初,AA 和 BB 试管都是空的,而 CC 试管是装满硫酸铜溶液的。有时,无脑博士把硫酸铜溶液从一个试管倒到另一个试管中,直到被灌试管装满或原试管空了。当然每一次灌注都是完全的。由于无脑博士天天这么折腾,早已熟练,溶液在倒的过程中不会有丢失。

写一个程序去帮助无脑博士找出当 AA 试管是空的时候,CC 试管中硫酸铜溶液所剩量的所有可能性。

输入格式

输入包括一行,为空格分隔开的三个数,分别为整数 A,B,CA,B,C

输出格式

输出包括一行,升序地列出当 AA 试管是空的时候,CC 试管溶液所剩量的所有可能性。

样例输入:

2 5 10

样例输出:

5 6 7 8 9 10

参考代码如下:

#include <iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<stack>
using namespace std;
struct state
{
    int a;
    int b;
    int c;
};
bool vis [21][21][21];
bool vis_c[21];
priority_queue<int>q;
state s;
int A,B,C;
int cnt=0;
void dfs()
{
   // cout<<s.a<<" "<<s.b<<" "<<s.c<<endl;
    vis[s.a][s.b][s.c]=1;
    if(s.a==0)
    {
    if(!vis_c[s.c])
    {
        q.push(s.c);
        vis_c[s.c]=1;cnt++;
    }
    }
    int t;
    if(s.a>0)
    {
        t=(s.b+s.a)<=B?s.a:B-s.b;//若a试管与b试管溶液的和不超过b试管容量,则倒光a中溶液,否则倒b试管剩余空间的体积(B-s.b),下同
        if(t>s.a)t=s.a;
        s.a-=t;s.b+=t;
        if(!vis[s.a][s.b][s.c])dfs();
        s.a+=t;s.b-=t;
        t=(s.c+s.a)<=C?s.a:C-s.c;
        if(t>s.a)t=s.a;
        s.a-=t;s.c+=t;
        if(!vis[s.a][s.b][s.c])dfs();
       s.a+=t;s.c-=t;
    }
    if(s.b>0)
    {
        t=(s.b+s.a)<=A?s.b:A-s.a;
        if(t>s.b)t=s.b;
        s.b-=t;s.a+=t;
        if(!vis[s.a][s.b][s.c])dfs();
        s.b+=t;s.a-=t;
        t=(s.b+s.c)<=C?s.b:C-s.c;
        if(t>s.b)t=s.b;
        s.b-=t;s.c+=t;
        if(!vis[s.a][s.b][s.c])dfs();
        s.b+=t;s.c-=t;
    }
    if(s.c>0)
    {
        t=(s.c+s.a)<=A?s.c:A-s.a;
        if(t>s.c)t=s.c;
        s.c-=t;s.a+=t;
        if(!vis[s.a][s.b][s.c])dfs();
        s.c+=t;s.a-=t;
        t=(s.c+s.b)<=B?s.c:B-s.b;
        if(t>s.c)t=s.c;
        s.c-=t;s.b+=t;
        if(!vis[s.a][s.b][s.c])dfs();
        s.c+=t;s.b-=t;
    }
}
int main()
{
   // freopen("C://Users/tushuguan/Desktop/acm.txt","r",stdin);
    cin>>A>>B>>C;
    s.a=0;s.b=0;s.c=C;
    memset(vis,sizeof(vis),false);
    memset(vis_c,sizeof(vis_c),false);
    dfs();
    int c;
    stack<int>sta;
    while(!q.empty())
    {
        c=q.top();
        q.pop();
        sta.push(c);
    }
    while(!sta.empty())
    {
        c=sta.top();
        sta.pop();
        cout<<c;
        if(!sta.empty())cout<<" ";
        else cout<<endl;
    }
  // fclose(stdin);
    return 0;
}

原文地址:https://www.cnblogs.com/linruier/p/9485202.html