[题解]分油问题

青春壹個敷衍的年華 提交于 2019-12-02 10:35:25

算法:广搜

解题思路:

因为要求最少的变换次数,所以很自然的想到要用广搜。广搜的初始状态为:10L的瓶子装满,其他的瓶子为空,接着只需要进行普通广搜即可。注意:因为有三个瓶子,故一共有6种移动状态:

1:从10L的瓶子向7L的瓶子中倒:

if(x10 > 0 && x7 < 7){
    x10 = x10 + x7 - 7;
    x7 = 7;
}

2:从7L的瓶子向3L的瓶子中倒:

if(x7 > 0 && x3 < 3){
    if(x7 + x3 > 3){
        x7 = x7 + x3 - 3;
        x3 = 3;
    }
    else{
        x3 = x7 + x3;
        x7 = 0;
    }
}

3:从10L的瓶子向3L的瓶子中倒:

if(x10 > 0 && x3 < 3){
    x10 = x10 + x3- 3;
    x3 = 3;
}

4:从7L的瓶子向10L的瓶子中倒:

if(x7 > 0){
    x10 = x10 + x7;
    x7 = 0;
}

5:从3L的瓶子向7L的瓶子中倒:

if(x3 > 0 && x 7 < 7){
    if(x3 + x7 > 7){
        x7 = 7;
        x3 = x3 = x7 - 7;
    }
    else {
        x7 = x3 + x7;
        x3 = 0;
    }
}

6:从3L的瓶子向10L的瓶子中倒:

if(x3 > 0){
    x10 = x10 + x3;
    x3 = 0;
}

源代码:

#include <bits/stdc++.h>
using namespace std;
int head,tail;
int v[1010][5];//v[head][1]:10L,v[head][2]:7L,v[head][3]:3L
bool pd(int x,int y,int z){
    bool f = true;
    for(int i  = 1;i <= tail;i++){
        if(v[i][1] == x && v[i][2] == y && v[i][3] == z)f = false;
    }
    return f;
}
void add(int x,int y,int z){
    tail++;
    v[tail][1] = x;
    v[tail][2] = y;
    v[tail][3] = z;
    v[tail][4] = head;
}
void print(int f){
    int ans[1010][5];
    int r = 0;
    while(v[f][4] != 0){
        r++;
        ans[r][1] = v[f][1];
        ans[r][2] = v[f][2];
        ans[r][3] = v[f][3];
        f = v[f][4];
    }
    for(int i = r;i >= 1;i--){
        cout<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<endl;
    }
}
int main(){
    v[1][1] = 10;v[1][2] = 0;v[1][3] = 0;v[1][4] = 0;
    head = 1,tail = 1;
    int x10,x7,x3;
    while(head <= tail){
        if(v[head][1] == 5 && v[head][2] == 5){
            print(head);
            exit(0);
        }
        if(v[head][1] > 0 && v[head][2] < 7){//10->7;
            x10 = v[head][1] + v[head][2] - 7;
            x7 = 7;
            x3 = v[head][3];
            if(pd(x10,x7,x3))add(x10,x7,x3);
        }
        if(v[head][1] > 0 && v[head][3] < 3){//10->3
            x10 = v[head][1] + v[head][3] - 3;
            x7 = v[head][2];
            x3 = 3;
            if(pd(x10,x7,x3))add(x10,x7,x3);
        }
        if(v[head][2] > 0 && v[head][3] < 3){//7->3
            if(v[head][2] + v[head][3] > 3){
                x7 = v[head][2] + v[head][3] - 3;
                x3 = 3;
            }
            else {
                x3 = v[head][2] + v[head][3];
                x7 = 0;
            }
            x10 = v[head][1];
            if(pd(x10,x7,x3))add(x10,x7,x3);
        }
        if(v[head][2] > 0){//7->10
            x10 = v[head][1] + v[head][2];
            x7 = 0;
            x3 = v[head][3];
            if(pd(x10,x7,x3))add(x10,x7,x3);
        }
        if(v[head][3] > 0 && v[head][2] < 7){//3->7
            if(v[head][3] + v[head][2] > 7){
                x7 = 7;
                x3 = v[head][3] - 7 + v[head][2];
            }
            else {
                x7 = v[head][3] + v[head][2];
                x3 = 0;
            }
            x10 = v[head][1];
            if(pd(x10,x7,x3))add(x10,x7,x3);
        }
        if(v[head][3] > 0){//3->10
            x10 = v[head][1] + v[head][3];
            x7 = v[head][2];
            x3 = 0;
            if(pd(x10,x7,x3))add(x10,x7,x3);
        }
        head++;
    }
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!