您的位置:首页 > 其它

HDU1495 非常可乐(BFS)

2011-09-02 21:49 323 查看
  刚拿到这题时很纠结,没有思路。后来想了一天,问了问高手终于把思路整理出来。

思路:三个瓶子,无非就是6种倒法,按杯子体积从大到小定义为s, m, n。则6种倒法分别是:s -> m, s -> n, m -> n, m -> s, n -> m, n -> s;

加一个标记变量,标记当前状态已经出现过。将没出现过的状态入队列,剩下的就是bfs的事了。。。

My Code:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
const int N = 100000;
struct coco
{
int s;
int m;
int n;
int step;
}q
;

int s, m, n;
int vis[101][101];

int bfs()
{
coco p, t;
int cnt, r = 0, f = 0;
q[0].s = s;
q[0].m = 0;
q[0].n = 0;
q[0].step = 0;
vis[m]
= 1;
r++;
while(f < r)
{
p = q[f++];
cnt = 0;
if(p.s == s/2)    cnt++;
if(p.m == s/2)    cnt++;
if(p.n == s/2)    cnt++;
if(cnt == 2)        //satisfied the term
return p.step;
if(p.s)
{
t = p;
if(t.m < m)    //s -> m
{
if(t.m + t.s > m)
{
t.s -= (m-t.m);
t.m = m;
}
else
{
t.m += t.s;
t.s = 0;
}
t.step++;
if(!vis[p.m][p.n])
{
vis[p.m][p.n] = 1;
q[r++] = t;
}
}
t = p;
if(t.n < n)    //s -> n
{
if(t.n + t.s > n)
{
t.s -= (n-t.n);
t.n = n;
}
else
{
t.m += t.s;
t.s = 0;
}
t.step++;
if(!vis[t.m][t.n])
{
vis[t.m][t.n] = 1;
q[r++] = t;
}
}
}
if(p.m)
{
t = p;    //m -> n
if(t.n < n)
{
if(t.n + t.m > n)
{
t.m -= (n-t.n);
t.n = n;
}
else
{
t.n += t.m;
t.m = 0;
}
t.step ++;
if(!vis[t.m][t.n])
{
vis[t.m][t.n] = 1;
q[r++] = t;
}
}

t = p;    // m -> s
t.s += t.m;
t.m = 0;
t.step ++;
if(!vis[t.m][t.n])
{
vis[t.m][t.n] = 1;
q[r++] = t;
}
}
if(p.n)
{
t = p;        // n -> m
if(t.n + t.m > m)
{
t.n -= (m - t.m);
t.m = m;
}
else
{
t.m += t.n;
t.n = 0;
}
t.step ++;
if(!vis[t.m][t.n])
{
vis[t.m][t.n] = 1;
q[r++] = t;
}

t = p;        //n -> s
t.s += t.n;
t.n = 0;
t.step ++;
if(!vis[t.m][t.n])
{
vis[t.m][t.n] = 1;
q[r++] = t;
}
}
}
return 0;
}

int main()
{
//freopen("data.in", "r", stdin);

int ans;
while(scanf("%d%d%d", &s, &n, &m), s||n||m)
{
memset(vis, 0, sizeof(vis));
if(m > n)
{
m = m+n;
n = m-n;
m = m-n;
}
if(s&1)        //if 's' is odd
{
printf("NO\n");
continue;
}
ans = bfs();
if(ans)
printf("%d\n", ans);
else
printf("NO\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: