计蒜客-题库-无脑博士的试管们
题目
无脑博士有三个容量分别是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:深度优先搜索。三个要点:1、判断边界,也就是什么时候一次搜索结束。一般当题目有确定的数据规模也就是n时,n可能就是边界。还有一种就是当把所有可能都搜索过了就结束,这就需要记录每一次搜索结果。搜索过的不再重复。确定边界后在到达边界时判断是否满足题目要求。2、当前该如何做。本题中就是往空试管里倒,从哪一个试管倒就“暴力”了。3、尝试每一种可能,结束当前可能进行下一个之前先还原。
代码
#include<iostream> using namespace std; int A, B, C; int res[21][21]; void dfs(int a,int b,int c){ res[a][b] = 1; int ta = a, tb = b,tc=c; if (a < A){ if (b>0){ if (b >= A - a){ b -= A - a; a = A; } else{ a += b; b = 0; } if (res[a][b] == 0){ dfs(a, b, c); } a = ta; b = tb; } if (c>0){ if (c >= A - a){ c -= A - a; a = A; } else{ a += c; c = 0; } if (res[a][b] == 0){ dfs(a, b, c); } a = ta; c = tc; } } if (b < B){ if (a>0){ if (a >= B - b){ a -= B - b; b = B; } else{ b += a; a = 0; } if (res[a][b] == 0){ dfs(a, b, c); } a = ta; b = tb; } if (c>0){ if (c >= B - b){ c -= B - b; b = B; } else{ b += c; c = 0; } if (res[a][b] == 0){ dfs(a, b, c); } b = tb; c = tc; } } if (c < C){ if (a>0){ if (a >= C - c){ a -= C - c; c = C; } else{ c += a; a = 0; } if (res[a][b] == 0){ dfs(a, b, c); } a = ta; c = tc; } if (b>0){ if (b >= C - c){ b -= C - c; c = C; } else{ c += b; b = 0; } if (res[a][b] == 0){ dfs(a, b, c); } b = tb; c = tc; } } } int main() { memset(res, 0, sizeof(res)); cin >> A >> B >> C; dfs(0, 0, C); bool flag = true; for (int i =20; i >=0; --i){ if (res[0][i]){ if (flag){ cout << C - i; flag = false; } cout << ' '<<C-i ; } } cout << endl; return 0; }
dfs函数写的确实烂(GG)
害怕失败的人,已经是一个loser!