标签:延伸 strong 定义 理解 不能 inpu block bfs tput
大家一定觉得运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升
可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
Input
三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。
Output
如果能平分的话请输出最少要倒的次数,否则输出"NO"。
Sample Input
7 4 3
4 1 3
0 0 0
Sample Output
NO
3
题目分析
深刻理解了广搜的用途,原来广搜还可以这儿用!
以后只要是等权的求最短路问题(最快,最少,最短)都可以往广搜上面想。
言归正传,我们来分析一下这道题。怎么说呢,刚刚看这道题的时候毫无头绪,然后没忍住往题目下面翻了翻评论,看到有位大佬说开一个三维数组,脑袋里面突然灵光一闪,这不就是类似于求迷宫的最短路吗!开一个三维数组,每一维用来表示三个瓶子的状态,数组的值则是从初始状态到该状态花了多少步,然后就是模拟倒水的操作,把倒水的操作看做是走迷宫的走路方式,然后bfs到尽头就行了。实际上就是从初始状态延伸出来的一棵解答树,我们去一层一层地搜。
剩下的见代码注释。
//PS:自己写的,代码有点粗糙,vJudge上面跑了七百多,未优化
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N = 120;
int s,n,m;
typedef struct Node
{
int x;
int y;
int z;
} V;//开一个结构体数组用来定义队列
queue<V> q;
int d[N][N][N];
void pour(int &x1,int &x2,int m)//模拟倒水操作,这里注意要先倒水再清空瓶子,即x2 += x1;x2 = m;两个步骤不能反了
{
if(x1<(m-x2))
{
x2 += x1;
x1 = 0;
}
else
{
x1 -= (m-x2);
x2 = m;
}
}
int Mymin(int x,int y,int z)//这里是一个小瑕疵
{
if(x == -1) x = 100000;
if(y == -1) y = 100000;
if(z == -1) z = 100000;
int t1 = min(x,y);
int t = min(t1,z);
return t;
}
int bfs()
{
memset(d,-1,sizeof d);
d[s][0][0] = 0;
V e;
e.x = s,e.y = 0,e.z = 0;
q.push(e);//把初始状态入队扩展
while (!q.empty())//队列不空就一直扩展
{
V t = q.front();
q.pop();
V k = t;
if(k.x>0)
{
pour(k.x,k.y,n);
if (d[k.x][k.y][k.z] == -1)
{
q.push(k);
d[k.x][k.y][k.z] = d[t.x][t.y][t.z] + 1;
}
k = t;
pour(k.x,k.z,m);
if (d[k.x][k.y][k.z] == -1)
{
q.push(k);
d[k.x][k.y][k.z] = d[t.x][t.y][t.z] + 1;
}
}
k = t;
if(k.y>0)
{
pour(k.y,k.x,s);
if (d[k.x][k.y][k.z] == -1)
{
q.push(k);
d[k.x][k.y][k.z] = d[t.x][t.y][t.z] + 1;
}
k = t;
pour(k.y,k.z,m);
if (d[k.x][k.y][k.z] == -1)
{
q.push(k);
d[k.x][k.y][k.z] = d[t.x][t.y][t.z] + 1;
}
}
k = t;
if(k.z>0)
{
pour(k.z,k.y,n);
if(d[k.x][k.y][k.z] == -1)
{
q.push(k);
d[k.x][k.y][k.z] = d[t.x][t.y][t.z] + 1;
}
k = t;
pour(k.z,k.x,s);
if(d[k.x][k.y][k.z] == -1)
{
q.push(k);
d[k.x][k.y][k.z] = d[t.x][t.y][t.z] + 1;
}
}
}
int ans = Mymin(d[s/2][s/2][0],d[s/2][0][s/2],d[0][s/2][s/2]);
return ans;
}
int main()
{
while (1)
{
cin>>s>>n>>m;
if(s == 0&&n == 0&&m == 0) break;
if(s%2)
{
printf("NO\n");
continue;
}
int res = bfs();
if(res == -1||res == 100000) printf("NO\n");
else printf("%d\n",res);
}
return 0;
}
标签:延伸 strong 定义 理解 不能 inpu block bfs tput
原文地址:https://www.cnblogs.com/Trouni/p/12663794.html