無腦博士有三個容量分別是A,B,C升的試管,A,B,C分別是三個從1到20的整數,最初,A和B試管都是空的,而C試管是裝滿硫酸銅溶液的。有時,無腦博士把硫酸銅溶液從一個試管倒到另外一個試管中,直到被灌試管裝滿或原試管空了。固然每一次灌注都是徹底的。因爲無腦博士每天這麼折騰,早已熟練,溶液在倒的過程當中不會有丟失。數組
寫一個程序去幫助無腦博士找出當A是個是空的時候,C試管中硫酸銅溶液所剩量的全部可能性。spa
輸入包括一行,爲空格分隔開的三個數,分別爲整數A,B和C。.net
輸出包括一行,升序地列出當A試管是空的時候,C試管溶液所剩量的全部可能性。code
思路:由於要求A爲空的時候C剩餘量的可能,仔細想一想這咋算,還有B容器呢,無從下手,百度了一下,參考的大神的思路,終於明白了,由於是A爲空,所以C中的液體的最後狀態只能一部分在C中一部分在B中,所以可將裝問題轉化成當A爲空時B的量,由此可想到,先求出A,B容器在博士每次交換液體時的狀態量,最後在這麼多狀態量中選擇A爲空的時候的狀態量blog
代碼以下(參考大神的)string
#include<stdio.h> #include<string.h> int a,c,b,A,B,C;//a,b,c表明此時A,B,C容器有多少水 int vis[25][25];//用VIS數組來表示每次變換時的A,B杯的狀態 void dfs(int a,int b,int c){ vis[a][b]=1;//狀態A杯爲a,B杯爲b if(a<A) //當A容器沒有裝滿時的狀況 { if(c>=A-a&&vis[A][b]==0)dfs(A,b,c-A+a);//從c倒入a中,C容器裏的大於A剩餘空間,可裝滿 if(c<A-a&&vis[a+c][b]==0)dfs(a+c,b,0); //c倒入a中,C容器裏的液體小於A的剩餘空間,如下也是 if(b>=A-a&&vis[A][b-A+a]==0)dfs(A,b-A+a,c); if(b<A-a&&vis[a+b][0]==0)dfs(a+b,0,c); } if(b<B){ if(c>=B-b&&vis[a][B]==0)dfs(a,B,c-B+b); if(c<B-b&&vis[a][b+c]==0)dfs(a,b+c,0);//從c倒入b if(a>=B-b&&vis[a-B+b][B]==0)dfs(a-B+b,B,c);//從a倒入b if(a<B-b&&vis[0][a+b]==0)dfs(0,a+b,c); } if(c<C){ if(a>=C-c&&vis[a-C+c][b]==0)dfs(a-C+c,b,C); if(a<C-c&&vis[0][b]==0)dfs(0,b,a+c);;//從a倒入c if(b>=C-c&&vis[a][b-C+c]==0)dfs(a,b-C+c,C); if(b<C-c&&vis[a][0]==0)dfs(a,0,b+c);//從b倒入c } } int main(){ scanf("%d%d%d",&A,&B,&C); memset(vis,0,sizeof(vis)); dfs(0,0,C); int flag=1; for(int i=B;i>=0;i--){ //以B的狀態來觀察A爲空的狀態 if(vis[0][i]) { if(flag) flag=0; else printf(" "); printf("%d",C-i); } } return 0; }
原文連接: http://blog.csdn.net/usher_ou/article/details/59186790io