您的位置:首页 > 其它

三个水杯 NYOJ BFS

2013-10-18 23:27 288 查看
三个水杯

时间限制:1000 ms | 内存限制:65535 KB

难度:4

描述

给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。

输入

第一行一个整数N(0<N<50)表示N组测试数据

接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的体积。

第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们需要的最终状态

输出

每行输出相应测试数据最少的倒水次数。如果达不到目标状态输出-1

样例输入

2

6 3 1

4 1 1

9 3 2

7 1 1

样例输出

3
-1

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
struct Node
{
int v[3];
int step;
Node(){memset(v,0,sizeof(v));}
};
Node st,ed;
Node cur,tp;

bool vis[1000010];
bool check(Node a,Node b)
{
for(int i=0;i<3;i++)
if(a.v[i]!=b.v[i]) return 0;
return 1;
}

int visnumber(Node a)
{
int num=0;
for(int i=0;i<3;i++)
num=num*100+a.v[i];
return num;
}
void bfs()
{
cur=st;
cur.v[1]=0;cur.v[2]=0;
queue<Node>q;
q.push(cur);
int mm=visnumber(cur);
vis[mm]=true;

while(!q.empty())
{
cur=q.front();q.pop();
if(check(cur,ed))
{printf("%d\n",cur.step);return;}
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
{
if(i==j) continue;
int carry=st.v[j]-cur.v[j];
if(carry>cur.v[i]) carry=cur.v[i];
tp=cur;
tp.v[i]-=carry;tp.v[j]+=carry;
mm=visnumber(tp);
if(vis[mm]==0)
{
tp.step++;
q.push(tp);
vis[mm]=true;

}

}

}

printf("-1\n");
}
int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
for(int i=0;i<3;i++) scanf("%d",&st.v[i]);
for(int i=0;i<3;i++) scanf("%d",&ed.v[i]);
st.step=0;
memset(vis,0,sizeof(vis));
bfs();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: