计蒜客——无脑博士的试管们

题目:

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

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

输入格式

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

输出格式

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

样例输入

2 5 10

样例输出

5 6 7 8 9 10

类型:DFS,动态规划

代码:

#include <iostream>
#include <math.h>
#include <stdio.h>
using namespace std;

int A,B,C;
//res[a][b] 存储A B中液体为a b的情况是否遍历过
int res[21][21];

//深搜 回溯
//参数为A B C 试管的液体总量
void backtrace(int a,int b,int c)
{
    res[a][b] = 1;
    int a0 = a, b0 = b, c0 = c;
    if(a < A){ //A未满
        if(b > 0){ //B -> A
            if(b >= A-a){ // A倒满
                b = b-A+a;
                a = A;
            }
            else{ //B倒空
                a += b;
                b = 0;
            }
            if(res[a][b] == 0)backtrace(a,b,c);
            a = a0;
            b = b0;
        }
        if(c > 0){ //C -> A
            if(c >= A-a){ // A倒满
                c = c-A+a;
                a = A;
            }
            else{ //C倒空
                a += c;
                c = 0;
            }
            if(res[a][b] == 0)backtrace(a,b,c);
            a = a0;
            c = c0;
        }
    }
    if(b < B){ //B未满
        if(a > 0){ //A -> B
            if(a >= B-b){ // B倒满
                a = a-B+b;
                b = B;
            }
            else{ //A倒空
                b += a;
                a = 0;
            }
            if(res[a][b] == 0)backtrace(a,b,c);
            a = a0;
            b = b0;
        }
        if(c > 0){ //C -> B
            if(c >= B-b){ // B倒满
                c = c-B+b;
                b = B;
            }
            else{ //C倒空
                b += c;
                c = 0;
            }
            if(res[a][b] == 0)backtrace(a,b,c);
            b = b0;
            c = c0;
        }
    }
    if(c < C){ //C未满
        if(a > 0){ //A -> C
            if(a >= C-c){ // C倒满
                a = a-C+c;
                c = C;
            }
            else{ //A倒空
                c += a;
                a = 0;
            }
            if(res[a][b] == 0)backtrace(a,b,c);
            a = a0;
            c = c0;
        }
        if(b > 0){ //B -> C
            if(b >= C-c){ // C倒满
                b = b-C+c;
                c = C;
            }
            else{ //B倒空
                c += b;
                b = 0;
            }
            if(res[a][b] == 0)backtrace(a,b,c);
            b = b0;
            c = c0;
        }
    }


}

int main()
{
    scanf("%d %d %d",&A,&B,&C);
    backtrace(0,0,C);
    /*for(int i=0; i<21; i++){
        for(int j=0; j<21; j++){
            cout << res[i][j] << " ";
        }
        cout << endl;
    }*/

    int k=0;
    for(int i=B; i >= 0; i--){
        //cout << res[0][i] << " ";
        if(res[0][i] == 1){
            if(k==0){
                cout << C-i;
                k=1;
            }
            else{
                cout << " " << C-i ;
            }
        }
    }
    cout << endl;

    return 0;
}

 PS: 注意输出格式,最后没有空格.....

原文地址:https://www.cnblogs.com/farewell-farewell/p/8672553.html