话说usaco是有多喜欢milk啊……看到milk3的时候那个囧……
Farmer John has three milking buckets of capacity A, B, and C liters. Each of the numbers A, B, and C is an integer from 1 through 20, inclusive. Initially, buckets A and B are empty while bucket C is full of milk. Sometimes, FJ pours milk from one bucket to another until the second bucket is filled or the first bucket is empty. Once begun, a pour must be completed, of course. Being thrifty, no milk may be tossed out.
Write a program to help FJ determine what amounts of milk he can leave in bucket C when he begins with three buckets as above, pours milk among the buckets for a while, and then notes that bucket A is empty.
PROGRAM NAME: milk3
INPUT FORMAT
A single line with the three integers A, B, and C.
SAMPLE INPUT (file milk3.in)
8 9 10
OUTPUT FORMAT
A single line with a sorted list of all the possible amounts of milk that can be in bucket C when bucket A is empty.
SAMPLE OUTPUT (file milk3.out)
1 2 8 9 10
SAMPLE INPUT (file milk3.in)
2 5 10
SAMPLE OUTPUT (file milk3.out)
5 6 7 8 9 10
死做法,貌似用了深搜。一开始可二可二的忘了每次把vis的值改为1.结果运行死循环直接跳出。后来有个地方想错了。就是wrong的地方,写成res【an+bn】了。查了很久。好在这题逻辑清晰,虽然写了很久但还没被搞晕。
最囧的是最后空格我反而记得处理了,却忘了回车- -。。。阴沟里翻船什么的唉……
/*
ID: wtff0411
PROG: milk3
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <vector>
#include <cmath>
#include <queue>
using namespace std;
int vis[22][22];
int res[22];
int a,b,c;
void solve(int an,int bn)
{
//cout<<an<<bn<<a<<b<<c<<endl;
//system("pause");
if(an!=a)
{
//cout<<a<<endl;
if(c-an-bn>=a-an)//put c in a
{
if(vis[a][bn]==0)
{
vis[a][bn]=1;//shit
solve(a,bn);
}
}
else
{
if(vis[an+c-an-bn][bn]==0)
{vis[an+c-an-bn][bn]=1;
solve(an+c-an-bn,bn);}
}
if(bn>=a-an)//put b in a
{if(vis[a][bn-a+an]==0)
{vis[a][bn-a+an]=1;
solve(a,bn-a+an);}
}
else
{
if(vis[an+bn][0]==0)
{vis[an+bn][0]=1;solve(an+bn,0);}
}
}
if(bn!=b)
{
// cout<<b<<endl;
if(c-an-bn>=b-bn)//put c in b
{
if(vis[an][b]==0)
{
if(an==0)
res[c-b]=1;
vis[an][b]=1;
solve(an,b);
}
}
else
{
if(vis[an][bn+c-an-bn]==0)
{
if(an==0)
res[0]=1;
vis[an][bn+c-an-bn]=1;
solve(an,bn+c-an-bn);}
}
if(an>b-bn)//put a in b
{if(vis[an-b+bn][b]==0)
{vis[an-b+bn][b]=1;
solve(an-b+bn,b);}}
else
{
res[c-an-bn]=1;//wrong
if(vis[0][an+bn]==0)
{vis[0][an+bn]=1;solve(0,an+bn);}
}
}
if((an+bn)!=0)
{
//return ;
//cout<<c<<endl;
if(vis[an][0]==0)//put b in c
{
vis[an][0]=1;
solve(an,0);
}
if(vis[0][bn]==0)//put a in c
{
vis[0][bn]=1;
res[c-bn]=1;
solve(0,bn);
}
}
//cout<<"aa"<<endl;
return ;
}
int main()
{
freopen("milk3.in","r",stdin);
freopen("milk3.out","w",stdout);
//int a,b,c;
//there is no doubt that i'm crazy for forgeting delete this after int them as global variables
cin>>a>>b>>c;
memset(vis,0,sizeof(vis));
memset(res,0,sizeof(res));
vis[0][0]=1;
res[c]=1;
solve(0,0);
int i=0;
/* if(b>=c)
res[0]=1;
else
res[0]=0;
*/
for(i=0;i<22;i++)
if(res[i]==1)
{cout<<i;
break;
}
for(i++;i<22;i++)
if(res[i]==1)
{cout<<" "<<i;
}
cout<<endl;
//system("pause");
return 0;
}
读了下题解- -。。瞎了。。
1.不用专门设res数组。最后反向循环一下vis【0】【i】就可以了。只要值为1,就输出c-i。省了好几个代码和纠结的地方。
2.sigh。判断vis=0和vis=1写在solve的开头就可以了……省了多少事啊混蛋!
3.可以把倒这个动作写一个函数,桶标为123,用一个双重循环,两个变量为倒出桶和倒入桶的编号。3个桶的时候还不明显,如果有多几个桶的话,那代码精简了n多啊泪。
1,3也就算了,2实在是要好好记住。是因为dfs还不熟吧一定是这样的一定是。。。