SOJ 1150.简单魔板
题目大意:中文题面,可直接看题目理解。
数据结构:
MagicPlate:
int up : 代表魔板上层的状态
int down : 代表魔板下层的状态
char op : 表示当前魔板状态是通过哪种操作('A'、'B'、'C')获得的
int pre : 代表通过op操作获得当前魔板状态的魔板状态(也即父节点)
vector<MagicPlate> vt : 模拟队列
解题思路:通过广搜对三叉树进行遍历。若发现重复状态,适当剪枝以降低复杂度。
代码如下:
1 #include <iostream> 2 #include <vector> 3 #include <string> 4 using namespace std; 5 6 class MagicPlate { 7 public: 8 void setUp(int u) { 9 up = u; 10 } 11 12 void setDown(int d) { 13 down = d; 14 } 15 16 bool stateEqual(const MagicPlate & mp) { 17 return up == mp.up && down == mp.down; 18 } 19 20 void reset() { 21 up = 1234; 22 down = 8765; 23 op = NULL; 24 pre = -1; 25 } 26 27 void operateA() { 28 int temp = up; 29 up = down; 30 down = temp; 31 32 op = 'A'; 33 } 34 35 void operateB() { 36 up = up / 10 + up % 10 * 1000; 37 down = down / 10 + down % 10 * 1000; 38 39 op = 'B'; 40 } 41 42 void operateC() { 43 int u = up % 1000 / 10; 44 int u1 = u / 10; 45 int u2 = u % 10; 46 int d = down % 1000 / 10; 47 int d1 = d / 10; 48 int d2 = d % 10; 49 50 up = up / 1000 * 1000 + d1 * 100 + u1 * 10 + up % 10; 51 down = down / 1000 * 1000 + d2 * 100 + u2 * 10 + down % 10; 52 53 op = 'C'; 54 } 55 56 void setPre(int p) { 57 pre = p; 58 } 59 60 int getPre() { 61 return pre; 62 } 63 64 char getOp() { 65 return op; 66 } 67 68 private: 69 int up; 70 int down; 71 char op; 72 int pre; 73 }; 74 75 vector<MagicPlate> vt; 76 string opStr; 77 int fp, rp; 78 int n; 79 80 void init() { 81 opStr = ""; 82 vt.clear(); 83 } 84 85 void getGoal(MagicPlate * mp) { 86 while (mp->getPre() != -1) { 87 opStr.push_back(mp->getOp()); 88 mp = &vt[mp->getPre()]; 89 } 90 } 91 92 bool visited(const MagicPlate &mp) { 93 //return false; 94 for (int i = 0; i <= fp; i++) { 95 if (vt[i].stateEqual(mp)) { 96 return true; 97 } 98 } 99 return false; 100 } 101 102 int main() { 103 while (cin >> n, n != -1) { 104 init(); 105 int temp; 106 int up = 0; 107 for (int i = 0; i < 4; i++) { 108 cin >> temp; 109 up = up * 10 + temp; 110 } 111 int down = 0; 112 for (int i = 0; i < 4; i++) { 113 cin >> temp; 114 down = down * 10 + temp; 115 } 116 MagicPlate targetMP; 117 targetMP.setUp(up); 118 targetMP.setDown(down); 119 120 MagicPlate begin; 121 begin.reset(); 122 vt.push_back(begin); 123 fp = 0; 124 rp = 1; 125 126 if (targetMP.stateEqual(begin)) { 127 cout << 0 << endl; 128 continue; 129 } 130 131 bool flag = false; 132 int step; 133 for (step = 1; step <= n; step++) { 134 int trp = rp; 135 while (fp < trp) { 136 MagicPlate mp = vt[fp]; 137 MagicPlate mpA(mp); 138 mpA.operateA(); 139 mpA.setPre(fp); 140 if (mpA.stateEqual(targetMP)) { 141 getGoal(&mpA); 142 flag = true; 143 break; 144 } else if (!visited(mpA)) { 145 vt.push_back(mpA); 146 rp++; 147 } 148 149 MagicPlate mpB(mp); 150 mpB.operateB(); 151 mpB.setPre(fp); 152 if (mpB.stateEqual(targetMP)) { 153 getGoal(&mpB); 154 flag = true; 155 break; 156 } else if (!visited(mpB)) { 157 vt.push_back(mpB); 158 rp++; 159 } 160 161 MagicPlate mpC(mp); 162 mpC.operateC(); 163 mpC.setPre(fp); 164 if (mpC.stateEqual(targetMP)) { 165 getGoal(&mpC); 166 flag = true; 167 break; 168 } else if (!visited(mpC)) { 169 vt.push_back(mpC); 170 rp++; 171 } 172 173 fp++; 174 } 175 if (flag) break; 176 } 177 178 if (flag) { 179 cout << step << " " << string(opStr.rbegin(), opStr.rend()) << endl; 180 } else { 181 cout << -1 << endl; 182 } 183 } 184 }