zoukankan      html  css  js  c++  java
  • POJ 3414 dfs 回溯

    题目链接:http://poj.org/problem?id=3414

    题意:三个值A, B, C, A和B是两个杯子的容量,问最短操作数使A或者B里的水量是C。有三种操作。

    思路:dfs.暴力 很简单。唯一不同的大概是这次做搜索都是自己想方设法的代码实现。中途很多问题。求得不是最大值。怎么保存操作过程。但好像不是原创方法。

    附AC代码:

      1 // dfs 开始觉得一定是bfs 我只要把两个杯子的各种操作遍历一遍 直到某个杯子里的水和C相等就结束。
      2 // 然后想到的是如何分开这两个杯子。因为一次操作改变的不一定是一个值。所以两个杯子的值也不能放在一个队列里遍历。
      3 // 于是。就是dfs。觉得回溯时dfs参数为空和不回溯dfs参数有两个都是可以的。
      4 // 详见代码。
      5 
      6 #include <stdio.h>
      7 #include <string.h>
      8 #include <iostream>
      9 using namespace std;
     10 
     11 int va, vb, c;
     12 int vis[110][110];
     13 int anss;
     14 string ans;
     15 string temp;
     16 
     17 void dfs(int aa, int bb, int step) {
     18        if (aa == c || bb == c) {
     19         if (anss > step) {
     20             anss = step;
     21             ans = temp;
     22         }
     23         return;
     24     }
     25     int a = aa, b = bb;
     26     vis[a][b] = 1;
     27     string t = "";
     28     // fill a
     29     if (a < va) {
     30         a = va;
     31         if (vis[a][b] == 0) {
     32           vis[a][b] = 1;
     33           t = temp;
     34           temp += "1";
     35           dfs(a, b, step+1);
     36           vis[a][b] = 0;
     37           temp = t;
     38         }
     39         a = aa;
     40     }
     41     // drop a
     42     if (a > 0) {
     43         a = 0;
     44          if (vis[a][b] == 0) {
     45           vis[a][b] = 1;
     46           t = temp;
     47           temp += "2";
     48           dfs(a, b, step+1);
     49           vis[a][b] = 0;
     50           temp =t;
     51         }
     52         a = aa;
     53     }
     54     // pour a to b
     55     if (a > 0 && b < vb) {
     56         int ma = min(a, vb-b);
     57         a -= ma;
     58         b += ma;
     59        if (vis[a][b] == 0) {
     60           vis[a][b] = 1;
     61           t = temp;
     62           temp += "3";
     63           dfs(a, b, step+1);
     64           vis[a][b] = 0;
     65           temp = t;
     66         }
     67         a = aa, b = bb;
     68     }
     69 
     70     // fill b
     71     if (b < vb) {
     72         b = vb;
     73        if (vis[a][b] == 0) {
     74           vis[a][b] = 1;
     75           t = temp;
     76           temp += "4";
     77           dfs(a, b, step+1);
     78           vis[a][b] = 0;
     79           temp = t;
     80         }
     81         b = bb;
     82     }
     83     // drop b
     84     if (b > 0) {
     85         b = 0;
     86         if (vis[a][b] == 0) {
     87           vis[a][b] = 1;
     88           t = temp;
     89           temp += "5";
     90           dfs(a, b, step+1);
     91           temp = t;
     92           vis[a][b] = 0;
     93         }
     94         b = bb;
     95     }
     96     // pour b to a
     97     if (b > 0 && a < va) {
     98         int mb = min(b, va-a);
     99         b -= mb;
    100         a += mb;
    101         if (vis[a][b] == 0) {
    102           vis[a][b] = 1;
    103           t = temp;
    104           temp += "6";
    105           dfs(a, b, step+1);
    106           temp = t;
    107           vis[a][b] = 0;
    108         }
    109         a = aa;
    110         b = bb;
    111     }
    112     return;
    113 }
    114 
    115 
    116 int main() {
    117     int a, b, step;
    118     while(cin >> va >> vb >> c) {
    119         anss = 1000000;
    120         a = 0, b = 0, step = 0;
    121         memset(vis, 0, sizeof(vis));
    122         temp = "";
    123         dfs(a, b, step);
    124         if (anss == 1000000) {
    125             cout << "impossible
    ";
    126             continue;
    127         }
    128         cout << anss << endl;
    129         int len = ans.length();
    130         for (int i=0; i<len; ++i) {
    131             if (ans[i] == '1') cout << "FILL(1)
    ";
    132             if (ans[i] == '2') cout << "DROP(1)
    ";
    133             if (ans[i] == '3') cout << "POUR(1,2)
    ";
    134             if (ans[i] == '4') cout << "FILL(2)
    ";
    135             if (ans[i] == '5') cout << "DROP(2)
    ";
    136             if (ans[i] == '6') cout << "POUR(2,1)
    ";
    137         }
    138     }
    139     return 0;
    140 }
    View Code
  • 相关阅读:
    python--模块与包
    内置函数 的总结
    迭代器 生成器 列表推导式 生成器表达式的一些总结
    函数的有用信息 带参数的装饰器 多个装饰器装饰一个函数
    函数名的应用(第一对象) 闭包 装饰器
    动态参数 名称空间 作用域 作用域链 加载顺序 函数的嵌套 global nonlocal 等的用法总结
    函数的初识 函数的返回值 参数
    文件操作 常用操作方法 文件的修改
    遍历字典的集中方法 集合的作用 以及增删查的方法
    计算机硬件的小知识
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5157420.html
Copyright © 2011-2022 走看看