POJ 3414 Pots (DFS || BFS)

31 篇文章 0 订阅

题目链接:Pots


解析:给定两个水瓶的大小a和b,以及目标c,输出最短操作使某一水瓶中剩下c容量的水。操作包括倒空、倒满、两瓶互相倒。


解法一:DFS

枚举每次可行的方案,并对枚举的上限做了限制,即如果当前的枚举次数已经大于目前最小次数解就剪枝。


AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int c, n, m, ans;
bool vis[110][110], tg;
char pa[10010][20], pp[10010][20];

void dfs(int x, int y, int dep){
    if(dep > ans) return ;
    if(x == c || y == c){
        if(dep < ans){
            ans = dep;
            tg = true;
            for(int i=0; i<ans; i++)
                strcpy(pa[i], pp[i]);
        }
        return ;
    }
    //FILL 1
    if(x < n && !vis[n][y]){
        vis[n][y] = true;
        strcpy(pp[dep], "FILL(1)");
        dfs(n, y, dep+1);
        vis[n][y] = false;
    }
    //FILL 2
    if(y < m && !vis[x][m]){
        vis[x][m] = true;
        strcpy(pp[dep], "FILL(2)");
        dfs(x, m, dep+1);
        vis[x][m] = false;
    }
    //DROP 1
    if(x > 0 && !vis[0][y]){
        vis[0][y] = true;
        strcpy(pp[dep], "DROP(1)");
        dfs(0, y, dep+1);
        vis[0][y] = false;
    }
    //DROP 2
    if(y > 0 && !vis[x][0]){
        vis[x][0] = true;
        strcpy(pp[dep], "DROP(2)");
        dfs(x, 0, dep+1);
        vis[x][0] = false;
    }
    //POUR 1 -> 2
    if(x > 0 && y < m){
        int t = min(x, m-y);
        if(!vis[x-t][y+t]){
            vis[x-t][y+t] = true;
            strcpy(pp[dep], "POUR(1,2)");
            dfs(x-t, y+t, dep+1);
            vis[x-t][y+t] = false;
        }
    }
    //POUR 2 -> 1
    if(y > 0 && x < n){
        int t = min(y, n-x);
        if(!vis[x+t][y-t]){
            vis[x+t][y-t] = true;
            strcpy(pp[dep], "POUR(2,1)");
            dfs(x+t, y-t, dep+1);
            vis[x+t][y-t] = false;
        }
    }
}

int main(){
//    freopen("in.txt", "r", stdin);
    while(scanf("%d%d%d", &n, &m, &c) == 3){
        memset(vis, false, sizeof(vis));
        ans = 0x7fffffff;
        tg = false;
        vis[0][0] = true;
        dfs(0, 0, 0);
        if(tg){
            printf("%d\n", ans);
            for(int i=0; i<ans; i++)
                puts(pa[i]);
        }
        else puts("impossible");
    }
    return 0;
}




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值