题目链接: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\n";
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)\n";
132             if (ans[i] == '2') cout << "DROP(1)\n";
133             if (ans[i] == '3') cout << "POUR(1,2)\n";
134             if (ans[i] == '4') cout << "FILL(2)\n";
135             if (ans[i] == '5') cout << "DROP(2)\n";
136             if (ans[i] == '6') cout << "POUR(2,1)\n";
137         }
138     }
139     return 0;
140 }
View Code

 

posted on 2016-01-25 14:43  小小八  阅读(187)  评论(0编辑  收藏  举报