普通的一道搜索题,注意按照状态搜索,并且注意在搜索的过程当中不能出现从空杯子中倒出水以及向满杯子中倒入水就可以了,紫书给出了详细的解析,具体实现如下:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
using namespace std;
struct node{
int cup[3];
int dist;
bool operator< (const node &a) const{
return dist > a.dist;
}
};
bool visit[220][220];
int ans[220];
int T, a, b, c, d;
void updateAns(node a){
for (int i = 0; i < 3; i++){
if (ans[a.cup[i]] == -1 || ans[a.cup[i]]>a.dist) ans[a.cup[i]] = a.dist;
}
}
void deal(){
int cup[3];
cup[0] = a; cup[1] = b; cup[2] = c;
node start;
start.cup[0] = 0; start.cup[1] = 0; start.cup[2] = c;
start.dist = 0;
priority_queue<node> q;
q.push(start);
visit[0][0] = true;
while (!q.empty()){
node front = q.top();
q.pop();
updateAns(front);
if (ans[d] != -1) break;
for (int i = 0; i < 3; i++){
if (front.cup[i] != 0){
for (int j = 0; j < 3; j++){
if (i != j&&front.cup[j]!=cup[j]){
node temp;
memcpy(&temp, &front, sizeof(front));
int water=min(cup[j]-temp.cup[j],temp.cup[i]);
temp.cup[i] -= water;
temp.cup[j] += water;
temp.dist += water;
if (!visit[temp.cup[0]][temp.cup[1]]){
q.push(temp);
visit[temp.cup[0]][temp.cup[1]] = true;
}
}
}
}
}
}
while (d >= 0){
if (ans[d] >= 0){
cout << ans[d] <<" "<<d<< endl;
break;
}
d--;
}
}
int main(){
cin >> T;
while (T--){
cin >> a >> b >> c >> d;
memset(visit,false,sizeof(visit));
memset(ans,-1,sizeof(ans));
deal();
}
return 0;
}