比较简单的隐式图搜索吧,建立状态结构体,然后暴力搜索出来,思路很明确,个人认为比较水的题了=-=
第一次读错题了,但是AC了,之后UVA加了几组数据WA了,改了一次又对了
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
#define MAX_SIZE 500000 + 10
struct State
{
int x;/*第一个杯子里的水*/
int y;/*第二个杯子里的水*/
int z;/*第三个杯子里的水*/
int step;
/*达到这个状态花费的步数*/
friend bool operator <(State a,State b){
if(a.step < b.step)
return true;
else
return false;
}
};
int v[3];/*杯子的容量*/
State St[MAX_SIZE];
int End_State;
int front,back;
int Steps,nearly,Cup;
int exchange(int &x,int &y,int n){ /*返回转移水的数量*/
/*将水从x倒向y,n为水杯的最大容量*/
int t=x-(n-y);
if(t > 0){
t=n-y;
x=x-(n-y);
y=n;
return t;
}
else{
t=x;
y=(x+y);
x=0;
return t;
}
}
bool Judge_ever(int x,int y,int z,int s){
for(int i=0;i < back;i++){
if(St[i].x==x && St[i].y==y && St[i].z==z && St[i].step <= s)
return true;
}
return false;/*这个状态不存在*/
}
void Judge_Nearly(int x,int y,int z,int step){
int a=End_State-x;
int b=End_State-y;
int c=End_State-z;
/*a,b,c代表他们和最终距离的差*/
if(a<=nearly && a>=0){
if(a < nearly){
Steps = step;
nearly=a;
}
else{
if(Steps > step){
Steps=step;
}
}
Cup=x;
} /*先比较状态是否接近,状态一样的话取最小的步数*/
if(b <= nearly && b>=0){
if(b < nearly){
Steps =step;
nearly=b;
}
else{
if(Steps>step){
Steps=step;
}
}
Cup=y;
}
if(c<=nearly && c>=0){
if(c<nearly){
Steps =step;
nearly=c;
}
else{
if(Steps>step){
Steps=step;
}
}
Cup=z;
}
}
void bfs(){
front=0,back=0;
Steps=0;
nearly=1<<30;/*最接近目标的值*/
St[back].x=0;
St[back].y=0;
St[back].z=v[2];
St[back].step=0;
back++;
while(front < back){
int sx=St[front].x;
int sy=St[front].y;
int sz=St[front].z;
int ss=St[front].step;
/*三杯水的状态 + 走到该状态的步数*/
front++;
Judge_Nearly(sx,sy,sz,ss);
/*如果有正好相等的返回这个步数*/
for(int d=0;d<6;d++){/*模拟倒水的状态*/
int x=sx;
int y=sy;
int z=sz;
int step=ss;
if(d==0) step+=exchange(x,y,v[1]);
else if(d==1) step+=exchange(x,z,v[2]);
else if(d==2) step+=exchange(y,x,v[0]);
else if(d==3) step+=exchange(y,z,v[2]);
else if(d==4) step+=exchange(z,x,v[0]);
else if(d==5) step+=exchange(z,y,v[1]);
if(!Judge_ever(x,y,z,step)){
St[back].x=x;
St[back].y=y;
St[back].z=z;
St[back].step=step;
back++;
}
}
}
}
int main()
{
int N;
scanf("%d",&N);
for(int cases=1;cases<=N;cases++){
for(int i=0;i<3;i++)
scanf("%d",&v[i]);
scanf("%d",&End_State);
bfs();
printf("%d %d\n",Steps,Cup);
}
return 0;
}