USACO之milk3

来源:互联网 发布:飞鸽传书网络连接失败 编辑:程序博客网 时间:2024/06/08 12:31

【题意】农民约翰有三个容量分别是A,B,C升的桶,A,B,C分别是三个从1到20的整数, 最初,A和B桶都是空的,而C桶是装满牛奶的。有时,农民把牛奶从一个桶倒到 另一个桶中,直到被灌桶装满或原桶空了。当然每一次灌注都是完全的。由于节约, 牛奶不会有丢失,写一个程序去帮助农民找出当A桶是空的时候,C桶中牛奶所剩量的所有可能性。
【输入】单独的一行包括三个整数A,B和C
【输出】只有一行,升序地列出当A桶是空的时候,C桶牛奶所剩量的所有可能性
【题解】初看这道题时,感觉不太懂,但是抓住一句话,‘’直到被灌桶装满或原桶空了‘’这说明当两个桶交互时,其中一个被灌满或者是空。这样一想就有多种情况了。

/*    ID:m1519591    PROG: milk3    LANG:C++*/#include<iostream>#include<fstream>#include<vector>#include<algorithm>using namespace std;const int MAX=22;int a[3]={0};   //此时桶中的牛奶量; //ifstream cin("milk3.in");//ofstream cout("milk3.out");bool vis[MAX][MAX][MAX]={0}; //表明此时3个桶中牛奶的状态。vector<int>ans;  //记录结果。 int a0[3]={0};  //桶的容量; void dfs(int a[]){    if(vis[a[0]][a[1]][a[2]])//如果此时的状态被访问过,就返回。     return ;    vis[a[0]][a[1]][a[2]]=true;    if(a[0]==0)    //当A桶中没有牛奶时,记录此时C桶中的牛奶数。     {        ans.push_back(a[2]);    }    for(int i=0;i<=2;i++)    {        if(a[i])  //i桶中有牛奶可以向其他桶中倒牛奶。         {            for(int j=0;j<=2;j++)            {                if(i!=j)                {                    int m=min(a[i],a0[j]-a[j]);                    a[i]-=m;                    a[j]+=m;                    if(!vis[a[0]][a[1]][a[2]])                    {                        dfs(a);       //将这种状态进行到底                                            //直到a[0]==0;                     }                    a[i]+=m;                    a[j]-=m;                }             }         }     } }int main(){    cin>>a0[0]>>a0[1]>>a0[2];     a[0]=0;    a[1]=0;    a[2]=a0[2];    dfs(a);    sort(ans.begin(),ans.end());    int i;    for(i=0;i<=ans.size()-2;i++)    cout<<ans[i]<<" ";    cout<<ans[i]<<endl;    return 0;}