HDOJ 1495 非常可乐 【bfs】
一共只有6种状态
a → b
a → c
b → a
b → c
c → a
c → b
bfs搜一遍即可
注意队列清空 标记数组清零
输入S为奇数时一定不符合要求,删除该情况剪枝
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int S, N, M;
typedef struct state{
int s, n, m; // 三个杯子的容量
int step; // 次数
}state;
queue<state> q;
bool vis[105][105][105];
bool End(int a, int b, int c){
if((a == b && c == 0) || (a == c && b == 0) || (b == c && a == 0)){
return true;
}
else
return false;
}
int bfs(){
memset(vis, 0, sizeof(vis));
while(!q.empty()) q.pop();
state start;
start.s = S, start.n = 0, start.m = 0, start.step = 0;
vis[S][0][0] = true;
//printf("start\n");
q.push(start);
while(!q.empty()){
state current, next;
int s, n, m, step; // current.
current = q.front();
s = current.s, n = current.n, m = current.m, step = current.step;
//printf("%d\t%d\t%d\n", s, n, m);
if(End(s, n, m)){ // 判断结束
//printf("%d\n", step);
return step;
}
next.step = step+1;
if(s > 0){ // a → b / c
if(s > N-n){ // a → b a有剩余
next.s = s-(N-n);
next.n = N;
next.m = m;
if(vis[next.s][next.n][next.m] == false){
vis[next.s][next.n][next.m] = true;
//printf("a → b a有剩余\n");
q.push(next);
}
}
else{ // a → b a无剩余
next.s = 0;
next.n = n+s;
next.m = m;
if(vis[next.s][next.n][next.m] == false){
vis[next.s][next.n][next.m] = true;
//printf("a → b a无剩余\n");
q.push(next);
}
}
if(s > M-m){ // a → c a有剩余
next.s = s-(M-m);
next.n = n;
next.m = M;
if(vis[next.s][next.n][next.m] == false){
vis[next.s][next.n][next.m] = true;
//printf("a → c a有剩余\n");
q.push(next);
}
}
else{ // a → c a无剩余
next.s = 0;
next.n = n;
next.m = m+s;
if(vis[next.s][next.n][next.m] == false){
vis[next.s][next.n][next.m] = true;
//printf("a → c a无剩余\n");
q.push(next);
}
}
}
if(n > 0){ // b → a / c
if(n > S-s){ // b → a b有剩余
next.s = S;
next.n = n - (S-s);
next.m = m;
if(vis[next.s][next.n][next.m] == false){
vis[next.s][next.n][next.m] = true;
//printf("b → a b有剩余\n");
q.push(next);
}
}
else{ // b → a b无剩余
next.s = s+n;
next.n = 0;
next.m = m;
if(vis[next.s][next.n][next.m] == false){
vis[next.s][next.n][next.m] = true;
//printf("b → a b无剩余\n");
q.push(next);
}
}
if(n > M-m){ // b → c b有剩余
next.s = s;
next.n = n - (M-m);
next.m = M;
if(vis[next.s][next.n][next.m] == false){
vis[next.s][next.n][next.m] = true;
//printf("b → c b有剩余\n");
q.push(next);
}
}
else{ // b → c b无剩余
next.s = s;
next.n = 0;
next.m = m+n;
if(vis[next.s][next.n][next.m] == false){
vis[next.s][next.n][next.m] = true;
//printf("b → c b无剩余\n");
q.push(next);
}
}
}
if(m > 0){ // c → a / b
if(m > S-s){ // c → a c有剩余
next.s = S;
next.n = n;
next.m = m - (S-s);
if(vis[next.s][next.n][next.m] == false){
vis[next.s][next.n][next.m] = true;
//printf("c → a c有剩余\n");
q.push(next);
}
}
else{ // c → a c无剩余
next.s = s+m;
next.n = n;
next.m = 0;
if(vis[next.s][next.n][next.m] == false){
vis[next.s][next.n][next.m] = true;
//printf("c → a c无剩余\n");
q.push(next);
}
}
if(m > N-n){ // c → b c有剩余
next.s = s;
next.n = N;
next.m = m - (N-n);
if(vis[next.s][next.n][next.m] == false){
vis[next.s][next.n][next.m] = true;
//printf("c → b c有剩余\n");
q.push(next);
}
}
else{ // c → b c无剩余
next.s = s;
next.n = n+m;
next.m = 0;
if(vis[next.s][next.n][next.m] == false){
vis[next.s][next.n][next.m] = true;
//printf("c → b c无剩余\n");
q.push(next);
}
}
}
q.pop();
}
return 0;
}
int main(){
while(~scanf("%d%d%d", &S, &N, &M)){
if(!S && !N && !M) break;
if(S & 1) printf("NO\n");
else{
int ans = bfs();
if(!ans) printf("NO\n");
else printf("%d\n", ans);
}
}
return 0;
}