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
  • 相关阅读:
    基于 IAR 修改工程名称
    Baidu IoT Study
    msp430f5438a Information Flash Seg Write -- Chapter
    MFC 编辑框内容更新方法以及滚动条设置
    通过打开按钮打开文件和通过左键移动打开文件并计算crc
    移动文件并将文件路径显示到编辑框内
    Aritronix Virtual Device 运行
    将一个char类型的数转换成曼切斯特数
    数组中重复的数字
    平衡二叉树
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5157420.html
Copyright © 2011-2022 走看看