方法 1:DFSDFSDFS因为牛奶的总量是不变的,所以可以用aaa,bbb中的牛奶量做状态,初始状态是(0,0)(0,0)(0,0),每次只能有6种选择,aaa倒bbb,aaa倒ccc,bbb倒aaa,bbb倒ccc,c倒aaa,ccc倒bbb。用一个数组vis[i][j]vis[i][j]vis[i][j]判重,s[i]s[i]s[i]记录ccc中所有可能值(s[i]=trues[i]=trues[i]=true表示ccc中可能出现iii),如果当前状态是(0,x)(0,x)(0,x),那么s[mc−x]=trues[mc
-x]=trues[mc−x]=true,最后输出sss中所有truetruetrue的就可以了。 用vis[i][j][k]vis[i][j][k]vis[i][j][k]也行,也就是说三维的也行。
方法 2 这个题目也可以递归…不过我不知道临界点是多少,就乱试了,结果用i=14i=14i=14能过…不过我不知道为什么iii要等于14,没证明过当iii等于14时能包括大多数的过程… (假如用BFS。只有在扩充的状态没有出现过的情况下,才把它加入队列,这样可以保证不重不漏)
方法3 人脑解法 这题简直是赤裸裸的奥数啊,直接手动算出所有的解再让计算机输出了就行了!估计只用0微秒 由于题目不对称(aaa要为000),导致了源代码的丑陋。分aaa小于bbb和aaa大于等于bbb两种情况,每种情况各有两种不同的方法,不断用bbb灌aaa,或者反之,如果灌完了就用ccc充满继续,如果充不满就说明做完了,如果灌满了还有就把被灌的倒回ccc,然后继续灌。最多做20次循环,因为c<=20c<=20c<=20 最后输出很简单,先遍历数组到c−1c-1c−1,之后再输出(ccc)就行(ccc永远是一个解)
方法4 使用枚举的方法,按照顺序A,B,CA,B,CA,B,C寻找每一个牛奶非空的桶,假设我们找到了BBB, 则接下来只能是从B→AB→AB→A或B→CB→CB→C或则什么都不做这三种情况;使用递归来完成。 我们需要一个数组state[500][3]state[500][3]state[500][3]来储存遍历过的三个桶中牛奶的状态, 当 当前状态已经在之前出现过,就退出。同样也是使用一个数组boolleavec[]bool leave_c[]boolleavec []来储存CCC中可能的牛奶量。.这样或许更容易理解。
方法5 使用二进制保存状态,因为A,B,CA,B,CA,B,C都在1−201-201−20之间,所以可以分别用8位表示他们的容量
然后分别对a−>b,a−>c,b−>c,b−>a,c−>a,c−>ba->b, a->c, b->c, b->a, c->a, c ->ba−>b,a−>c,b−>c,b−>a,c−>a,c−>b六种情况进行DFSDFSDFS, 用一个数组保存已经判断过的状态。
方法6 将iii从000到ccc带入一个boolboolbool函数fff(iii定义:ccc桶为iii,aaa桶空),fff的功能是bfs遍历到状态为(x,x,i)(x,x,i)(x,x,i),判断能否遍历到或者此时的状态aaa是否为0;这样做效率貌似是很低的,不过可以加一个数组p[]p[]p[],设定为全局变量,在遍历时遇到(0,x,i)(0,x,i)(0,x,i)的状态就记录,另外在将iii带入fff前判断p[i]p[i]p[i]是否记录过,这样一来效率大大提高了。
上代码
(减少代码复制,创造美好ACGO)