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

刚开始以为这道题是对所有情况进行分类,发现有几个情况是很难直接找出来的,是一个循环的过程。
后来听大佬说这个题用DFS做,当时有些蒙,,,咋用DFS 静下心来想一想,发现是有规律的,A桶只能到给B桶和C桶,B桶C桶同理。也就是说,用递归把所有可能的组合方式都跑一遍,找出其中满足条件的C桶的容量。(感觉会T,会爆栈的呀) 对于固定的方式,可用DFS搜索全部状态。
 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0);
const double e=exp();
const int N = ; int x,y,z,cnt=;
int check[][][],ans[]; bool cmp(int a,int b)
{
return a<b;
}
void DFS(int a,int b,int c)
{
if(a!=&&b!=&&c!=z)
check[a][b][c]=;
if(a==&&check[a][b][c]!=)
{
check[a][b][c]=;
ans[cnt++]=c;
} if(a)
{
if(b!=y)
{
if(a>=(y-b))
if(check[a-(y-b)][y][c]==)
DFS(a-(y-b),y,c);
if(a<(y-b))
if(check[][b+a][c]==)
DFS(,b+a,c);
}
if(c!=z)
{
if(a>=(z-c))
if(check[a-(z-c)][b][z]==)
DFS(a-(z-c),b,z);
if(a<(z-c))
if(check[][b][c+a]==)
DFS(,b,c+a);
}
}
if(b)
{
if(a!=x)
{
if(b>=(x-a))
if(check[x][b-(x-a)][c]==)
DFS(x,b-(x-a),c);
if(b<(x-a))
if(check[a+b][][c]==)
DFS(a+b,,c);
}
if(c!=z)
{
if(b>=(z-c))
if(check[a][b-(z-c)][z])
DFS(a,b-(z-c),z);
if(b<(z-c))
if(check[a][][c+b])
DFS(a,,c+b);
}
}
if(c)
{
if(a!=x)
{
if(c>=(x-a))
if(check[x][b][c-(x-a)]==)
DFS(x,b,c-(x-a));
if(c<(x-a))
if(check[a+c][b][]==)
DFS(a+c,b,);
}
if(b!=y)
{
if(c>=(y-b))
if(check[a][y][c-(y-b)]==)
DFS(a,y,c-(y-b));
if(c<(y-b))
if(check[a][b+c][]==)
DFS(a,b+c,);
}
}
} int main()
{
int i,p,j,n;
scanf("%d%d%d",&x,&y,&z);
check[][][z]=;
ans[]=z;
DFS(,,z);
sort(ans,ans+cnt,cmp);
printf("%d",ans[]);
for(i=;i<cnt;i++)
printf(" %d",ans[i]);
putchar('\n');
return ;
}
 
05-21 04:24