题目链接: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 }