原题链接:http://cerberus.delos.com:791/usacoprob2?a=s1DTJaMre3q&S=milk3
分析与思路:不难看出共有六种到牛奶的方式,a->b,a->c,b->a,b->c,c->a,c->b。但是每次倒完后的状态不一定一样的,不一样的状态在进行六种不同方式的倾倒,
又可以产生不一样的状态。这就需要来记录每个状态是否出现过,当出现过时就直接返回到函数出口,进行上一层的下一次变换,若没有出现过此状态就继
续进行这六种方式的变换。深度优先搜索示意图如下:
以下是代码执行流程图的一部分(以8,9,10为例进行搜索):
代码:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int A,B,C;
int used[21][21][21],recorder[21];
void DFS(int a,int b,int c)
{
if(used[a][b][c])return ;
else used[a][b][c]=1;
if(a==0&&!recorder[c])
recorder[c]=1;
//把c倒入a
if(c>=A-a)DFS(A,b,c-A+a);
else DFS(a+c,b,0);
//把c倒入b
if(c>=B-b)DFS(a,B,c-B+b);
else DFS(a,b+c,0);
//把b倒入a
if(b>=A-a)DFS(A,b-A+a,c);
else DFS(a+b,0,c);
//把b倒入c
if(b>=C-c)DFS(a,b-C+c,C);
else DFS(a,0,b+c);
//把a倒入b
if(a>=B-b)DFS(a-B+b,B,c);
else DFS(0,a+b,c);
//把a倒入c
if(a>=C-c)DFS(a-C+c,b,C);
else DFS(0,b,a+c);
}
int main() {
ofstream fout ("milk3.out");
ifstream fin ("milk3.in");
cin>>A>>B>>C;
DFS(0,0,C);
int count=0;
for(int i=0;i<=C;i++)
{
if(recorder[i])
{
count++;
if(count==1)
cout<<i;
else
cout<<" "<<i;
}
}
cout<<endl;
return 0;
}
再来看看类似的题目:之前做的全国软件大赛的泊松分酒。
题目要求由用户输入:各个容器的容量,开始的状态,和要求的目标油量,通过计算输出实现的步骤。以上代码只要记录一下成功时的遍历路径即可
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int A,B,C;
int used[21][21][21],recorder[21];
int path[100][3];
int path_index=0;
int N,count=0;
void DFS(int a,int b,int c)
{
path[path_index][0]=a;
path[path_index][1]=b;
path[path_index][2]=c;
++path_index;
if(used[a][b][c])return ;
else used[a][b][c]=1;
if(a==N||b==N||c==N){
count++;
cout<<"第"<<count<<"个"<<endl;
for(int i=0;i<path_index;i++)
cout<<path[i][0]<<" "<<path[i][1]<<" "<<path[i][2]<<endl;
cout<<"--------------------------------------------"<<endl;
}
//把c倒入a
if(c>=A-a)DFS(A,b,c-A+a);
else DFS(a+c,b,0);
--path_index;
//把c倒入b
if(c>=B-b)DFS(a,B,c-B+b);
else DFS(a,b+c,0);
--path_index;
//把b倒入a
if(b>=A-a)DFS(A,b-A+a,c);
else DFS(a+b,0,c);
--path_index;
//把b倒入c
if(b>=C-c)DFS(a,b-C+c,C);
else DFS(a,0,b+c);
--path_index;
//把a倒入b
if(a>=B-b)DFS(a-B+b,B,c);
else DFS(0,a+b,c);
--path_index;
//把a倒入c
if(a>=C-c)DFS(a-C+c,b,C);
else DFS(0,b,a+c);
--path_index;
}
int main() {
ofstream fout ("milk3.out");
ifstream fin ("milk3.in");
cin>>A>>B>>C;
int a,b,c;
cin>>a>>b>>c;
cin>>N;
DFS(a,b,c);
return 0;
}