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; }