Description
农民约翰有三个容量分别是A,B,C升的桶,A,B,C分别是三个从1到20的整数,最初,A和B桶都是空的,而C桶是装满牛奶的。有时,约翰把牛奶从一个桶倒到另一个桶中,直到被灌桶装满或原桶空了。当然每一次灌注都是完全的。由于节约,牛奶不会有丢失。 写一个程序去帮助约翰找出当A桶是空的时候,C桶中牛奶所剩量的所有可能性。
Input
单独的一行包括三个整数A,B和C。
Output
只有一行,列出当A桶是空的时候,C桶牛奶所剩量的所有可能性。
Sample Input
8 9 10
Sample Output
1 2 8 9 10
题意:
起初 A B 桶是空的,C 桶是满的,C桶的牛奶可以倒到 A B桶中,停止的条件是 A B 变满或者 C桶变空
解释一下样例:
1、C桶中的牛奶倒进A 桶中,A 满停止运行,此时 C桶剩余 2
2、C桶中的牛奶倒进B 桶中,B 满停止运行,此时 C桶剩余 1
3、C桶中的牛奶倒进A桶中 8,B桶中 2,把A桶中的牛奶倒进 C中,A空,C桶剩余 8
4、C桶中的牛奶倒进B桶中 9,A桶中 1,把B桶中的牛奶倒进 C中,B空,C桶剩余 9
5、C桶中的牛奶倒进A桶中 8,B桶中 2,把A桶中的牛奶倒进 C中,B同种的牛奶倒进C中,AB空,C桶剩余 10
思路:
DFS 搜索所有的情况
首先列出所有的情况: C->A, C->B,A->B,A->C,B->A,B->C
每一种情况又分为两种情况,倒的桶是否能够使 被倒桶 倒满
例如 C->A
(1) C能使 A满,A的现有容量是 a(A桶的体积),B桶现有容量不变,C桶减去原来A桶缺少的
(2)C不能使A满,A的现有容量为原来的容量+C现有的容量,B桶容量不变,C桶容量变为 0
C->B 的时候,不用去判断 A此时满不满,因为12 种DFS,总有一种情况能够去判断A满不满的情况
DFS确定结束条件:
如果当前容量已经搜索过了,就结束当前搜索
用三维 vis 数组记录是否已经搜索过
CODE
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define memset(a,n) memset(a,n,sizeof(n))
typedef long long LL;
#define memset(a,n) memset(a,n,sizeof(a))
int a,b,c;
int ans[30];
int flag=0;
int vis[30][30][30];
void DFS(int x,int y,int z)
{
if(vis[x][y][z]==1)
return ;
else
vis[x][y][z]=1;
if (x == 0)
ans[flag++] = z;
if(z-a+x>=0)
DFS(a,y,z-a+x);
else
DFS(x+z,y,0);
if(x-c+z>=0)
DFS(x-c+z,y,c);
else
DFS(0,y,z+x);
if(z-b+y>=0)
DFS(x,b,z-b+y);
else
DFS(x,y+z,0);
if(y-c+z>=0)
DFS(x,y-c+z,c);
else
DFS(x,0,z+y);
if(x-b+y>=0)
DFS(x-b+y,b,z);
else
DFS(0,y+x,z);
if(y-a+x>=0)
DFS(a,y-a+x,z);
else
DFS(x+y,0,z);
}
int main()
{
scanf("%d %d %d",&a,&b,&c);
memset(ans,0);
memset(vis,0);
DFS(0,0,c);
//cout<<flag<<endl;
sort(ans,ans+flag);
for (int i=0; i<flag; i++)
{
if(i<flag-1)
printf("%d ",ans[i]);
else
printf("%d\n",ans[i]);
}
}