http://acm.uestc.edu.cn/#/status/list?problemId=470
///*470 倒水问题*/
#include<iostream>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
int a[3];///*3个杯子*/
int n;///*需要凑的n*/
int vis[1001][1001];///*访问数组*/
struct Node
{
int bz[3], step;
};
queue<Node> q;
int bfs()
{
while(!q.empty())
q.pop();
q.push(Node{a[0],0,0,0});
while(!q.empty())
{
Node s = q.front();
Node ss;///*Node() {} 这个不写 这一句报错 妈的~~~...*/
q.pop();///*s出队*/
if(s.bz[0] == n || s.bz[1] == n || s.bz[2] == n)///*判断其中一个是否到达n*/
return s.step;
for(int i = 0; i < 3; i++)///*循环杯子[i]向杯子[j]中倒水*/
for(int j = 0; j < 3; j++)
{
if(i == j)
continue;///*自己不能给自己倒水~;*/
int cha = a[j] - s.bz[j];///*杯子[j]此时还能放下多少水~*/
ss = s;///**这个可以直接用s 不过还是为了以防万一 另写一个结构体对象吧/
if(ss.bz[i] && cha)
{
if(ss.bz[i] > cha)///*表示能beizi[i]能向被子j里倒水 且能剩余*/
{
ss.bz[j] = a[j];///*倒满了*/
ss.bz[i] -= cha;///*杯子[i] 减去到的水*/
}
else///*剩不下 直接全部给杯子[j]*/
{
ss.bz[j] += ss.bz[i];///*全部给被子[j]*/
ss.bz[i] = 0;
}
if(!vis[ss.bz[0]][ss.bz[1]])///*未访问 1 2 未访问 vis[a[0]][a[1]][a[2]就不可能被访问了] 如果只看0的话 会少东西` 就相当于 5 4 3凑 5 0 0 变成 0 4 1 .. 0 3 2 不准确*/
{
vis[ss.bz[0]][ss.bz[1]] = 1;///*置1*/
q.push(Node{ss.bz[0], ss.bz[1], ss.bz[2], ss.step+1});///*入队步数加1*/
}
}
}
}
return -1;
}
int main ()
{
while(cin>>a[0]>>a[1]>>a[2])
{
cin>>n;
// sort(a, a+3, compare);///*调用上面的compare函数*/
memset(vis, 0, sizeof(vis));///*初始化0*/
int ans = bfs();
if(ans == -1)///*-1的时候表示凑不到数 所以输出NO*/
cout<<"NO"<<endl;
else
cout<<ans<<endl;
}
return 0;
}