题目
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…
农民约翰有三个容量分别是A,B,C升的桶,A,B,C分别是三个从1到20的整数, 最初,A和B桶都是空的,而C桶是装满牛奶的。有时,农民把牛奶从一个桶倒到另一个桶中,直到被灌桶装满或原桶空了。当然每一次灌注都是完全的。由于节约,牛奶不会有丢失。
写一个程序去帮助农民找出当A桶是空的时候,C桶中牛奶所剩量的所有可能性。
题解
记忆化搜索,搜索所有可能性
每次从非空的桶尝试往另外两个桶倒牛奶
代码
/*
ID: yjy_aii1
TASK: milk3
LANG: C++
*/
#include <cstdio>
#include <algorithm>
using namespace std;
int a,b,c;
int bz[24][24][24];
bool cz[24];
void dfs(int x,int y,int z){
if (bz[x][y][z]==1) return;
bz[x][y][z]=1;
if (x==0) cz[z]=1;
if (x>0){
if (y<b) dfs(x-min(x,b-y),y+min(x,b-y),z);
if (z<c) dfs(x-min(x,c-z),y,z+min(x,c-z));
}
if (y>0){
if (x<a) dfs(x+min(y,a-x),y-min(y,a-x),z);
if (z<c) dfs(x,y-min(y,c-z),z+min(y,c-z));
}
if (z>0){
if (x<a) dfs(x+min(z,a-x),y,z-min(z,a-x));
if (y<b) dfs(x,y+min(z,b-y),z-min(z,b-y));
}
}
int main(){
freopen("milk3.in","r",stdin);
freopen("milk3.out","w",stdout);
scanf("%d%d%d",&a,&b,&c);
dfs(0,0,c);
int i=0;
while (!cz[i]&&i<=c) i++;
printf("%d",i);
i++;
for (i;i<=c;i++)
if (cz[i]) printf(" %d",i);
printf("\n");
}
清秋凝冰河
义无反顾的洛河啊
你是渭水的孩子
渭水是黄河的孩子
你奔涌,你狂躁,你决绝
像黄河渭水一样的自高原流下
你凌厉的水花打湿了姑娘的面颊
清秋,清秋,这清冷的深秋
终于是你安宁的时候
洛河凝结成冰,还清秋一季清静
刹那间,冰封山巅,偷得转瞬清闲,已是天上人间
“铁马冰河入梦来”