HDU 1495 非常可乐

非常可乐

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7535    Accepted Submission(s): 3005


Problem Description
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是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,但是需要注意的是这个题不是分出来二分之一的总量就完事了,还要再凑出来一个二分之一的总量,这个就比较简单了,那就是在步数上加1就好。 

然而代码太丑了。写的超级麻烦。以后绝对不这么写了。

/*************************************************************************
	> File Name: 非常可乐.cpp
	> Author: Zhanghaoran0
	> Mail: [email protected]
	> Created Time: 2015年08月18日 星期二 08时27分37秒
 ************************************************************************/

#include 
#include 
#include 
#include 

using namespace std;
/*
int S, N, M;
bool flag[105][105];
int Max = 1000001;
bool dfs(int x, int y, int z, int step){
    if(x == S / 2 || y == S / 2 || z == S / 2){
        Max = min(Max, step + 1); 
	return true;
    }
    if(!flag[N][y]){
        flag[N][y] = true;
        dfs(N, y, z - x, step + 1);
        flag[N][y] = false;
    }
    if(!flag[x][M]){
        flag[x][M] = true;
        dfs(x, M, z - y, step + 1);
        flag[x][M] = false;
    }
    
    if(x != 0 || y != 0){
        if(x + y > N){
            if(!flag[N][y - (N - x)]){
                flag[N][y - (N - x)] = true;
                dfs(N, y - (N - x), z, step + 1);
                flag[N][y - (N - x)] = false;
            }
        }
        else if(x + y <= N){
            if(!flag[x + y][0]){
                flag[x + y][0] = true;
                dfs(x + y, 0, z, step + 1);
                flag[x + y][0] = false;
            }
        }
        if(x + y > M){
            if(!flag[x - (M - y)][M]){
                flag[x - (M - y)][M] = true;
                dfs(x - (M - y), M, z, step + 1);
                flag[x - (M - y)][M] = false;
            }
            
        }
        else if(x + y <= M){
            if(!flag[0][x + y]){
                flag[0][x + y] = true;
                dfs(0, x + y, z, step + 1);
                flag[0][x + y] = false;
            }
        }

        if(!flag[0][y]){
            flag[0][y] = true;
            dfs(0, y, z + x, step + 1);
            flag[0][y] = false;
        }

        if(!flag[x][0]){
            flag[x][0] = true;
            dfs(x, 0, y + z, step + 1);
            flag[x][0] = false;
        }
    }
}


int main(void){
    while(1){
        cin >> S >> N >> M;
        if(S == 0 && N == 0 && M == 0)
            break;
        if(S % 2){ 
            cout << "NO" << endl;
            continue;
        }
        
        memset(flag, 0, sizeof(flag));

        dfs(0, 0, S, 0);
        if(Max != 1000001)
            cout << Max << endl;
        else
            cout << "NO" << endl;
        Max = 1000001;
    }
    return 0;
}
*/



bool flag[105][105];
int S, N, M;
int goal;
struct node{
    int nowpos[3];
    int step;
}q[1000001];
int ans;


int  bfs(){
    int head = 0;
    int tail = 1;
    q[0].nowpos[0] = S;
    q[0].nowpos[1] = 0;
    q[0].nowpos[2] = 0;
    q[0].step = 0;
    flag[0][0] = true;

    while(head < tail){
        int num = 0;
        if(q[head].nowpos[0] == goal)
            num ++;
        if(q[head].nowpos[1] == goal)
            num ++;
        if(q[head].nowpos[2] == goal)
            num ++;
        if(num == 2)
            return q[head].step;

        if(q[head].nowpos[0] != 0){
            if(q[head].nowpos[0] > N - q[head].nowpos[1]){
                q[tail].nowpos[0] = q[head].nowpos[0] - (N - q[head].nowpos[1]);
                q[tail].nowpos[1] = N;
                q[tail].nowpos[2] = q[head].nowpos[2];
                q[tail].step = q[head].step + 1;
            }
            else{
                q[tail].nowpos[0] = 0;
                q[tail].nowpos[1] = q[head].nowpos[1] + q[head].nowpos[0];
                q[tail].nowpos[2] = q[head].nowpos[2];
                q[tail].step = q[head].step + 1;
            }

            if(!flag[q[tail].nowpos[1]][q[tail].nowpos[2]]){
                flag[q[tail].nowpos[1]][q[tail].nowpos[2]] = true;
                tail ++;
            }

            if(q[head].nowpos[0] > M - q[head].nowpos[2]){
                q[tail].nowpos[0] = q[head].nowpos[0] - (M - q[head].nowpos[2]);
                q[tail].nowpos[1] = q[head].nowpos[1];
                q[tail].nowpos[2] = M;
                q[tail].step = q[head].step + 1;
            }
            else{
                q[tail].nowpos[0] = 0;
                q[tail].nowpos[2] = q[head].nowpos[2] + q[head].nowpos[0];
                q[tail].nowpos[1] = q[head].nowpos[1];
                q[tail].step = q[head].step + 1;
            }

            if(!flag[q[tail].nowpos[1]][q[tail].nowpos[2]]){
                flag[q[tail].nowpos[1]][q[tail].nowpos[2]] = true;
                tail ++;
            }
        }



        if(q[head].nowpos[1] != 0){
            if(q[head].nowpos[1] > S - q[head].nowpos[0]){
                q[tail].nowpos[0] = S;
                q[tail].nowpos[1] = q[head].nowpos[1] - S + q[head].nowpos[0];
                q[tail].nowpos[2] = q[head].nowpos[2];
                q[tail].step = q[head].step + 1;
            }
            else{
                q[tail].nowpos[1] = 0;
                q[tail].nowpos[0] = q[head].nowpos[1] + q[head].nowpos[0];
                q[tail].nowpos[2] = q[head].nowpos[2];
                q[tail].step = q[head].step + 1;
            }

            if(!flag[q[tail].nowpos[1]][q[tail].nowpos[2]]){
                flag[q[tail].nowpos[1]][q[tail].nowpos[2]] = true;
                tail ++;
            }

            if(q[head].nowpos[1] > M - q[head].nowpos[2]){
                q[tail].nowpos[1] = q[head].nowpos[1] - (M - q[head].nowpos[2]);
                q[tail].nowpos[0] = q[head].nowpos[0];
                q[tail].nowpos[2] = M;
                q[tail].step = q[head].step + 1;
            }
            else{
                q[tail].nowpos[1] = 0;
                q[tail].nowpos[2] = q[head].nowpos[2] + q[head].nowpos[1];
                q[tail].nowpos[0] = q[head].nowpos[0];
                q[tail].step = q[head].step + 1;
            }

            if(!flag[q[tail].nowpos[1]][q[tail].nowpos[2]]){
                flag[q[tail].nowpos[1]][q[tail].nowpos[2]] = true;
                tail ++;
            }
        }

	    if(q[head].nowpos[2] != 0){
            if(q[head].nowpos[2] > S - q[head].nowpos[0]){
                q[tail].nowpos[0] = S;
                q[tail].nowpos[2] = q[head].nowpos[2] - S + q[head].nowpos[0];
                q[tail].nowpos[1] = q[head].nowpos[1];
                q[tail].step = q[head].step + 1;
            }
            else{
                q[tail].nowpos[2] = 0;
                q[tail].nowpos[0] = q[head].nowpos[2] + q[head].nowpos[0];
                q[tail].nowpos[1] = q[head].nowpos[1];
                q[tail].step = q[head].step + 1;
            }

            if(!flag[q[tail].nowpos[1]][q[tail].nowpos[2]]){
                flag[q[tail].nowpos[1]][q[tail].nowpos[2]] = true;
                tail ++;
            }

            if(q[head].nowpos[2] > N - q[head].nowpos[1]){
                q[tail].nowpos[2] = q[head].nowpos[2] - (N - q[head].nowpos[1]);
                q[tail].nowpos[0] = q[head].nowpos[0];
                q[tail].nowpos[1] = N;
                q[tail].step = q[head].step + 1;
            }
            else{
                q[tail].nowpos[2] = 0;
                q[tail].nowpos[1] = q[head].nowpos[2] + q[head].nowpos[1];
                q[tail].nowpos[0] = q[head].nowpos[0];
                q[tail].step = q[head].step + 1;
            }

            if(!flag[q[tail].nowpos[1]][q[tail].nowpos[2]]){
                flag[q[tail].nowpos[1]][q[tail].nowpos[2]] = true;
                tail ++;
            }
        }
        head ++;
    }
    return -1;
}



int main(void){
    while(1){
        cin >> S >> N >> M;
        if(S == 0 && N == 0 && M == 0)
            break;
        if(S % 2){
            cout << "NO" << endl;
            continue;
        }
        
        goal = S / 2;
        memset(flag, 0, sizeof(flag));
        ans = bfs();
        if(ans == -1)
            cout << "NO" << endl;
        else 
            cout << ans << endl;
    }
    return 0;
}


你可能感兴趣的:(搜索专题)