题目大意:和soj 1150题目大意差不多,不过数据规模变大了,n可能大于10。
解题思路:在1150的基础上作修改,修改状态重复判断的方式。以前是:扫描整个队列,查重;现在是:引入set集合,每个元素只记录up和down的值,进行查重。
代码如下:
1 #include <iostream> 2 #include <vector> 3 #include <string> 4 #include <set> 5 using namespace std; 6 7 class MagicPlate { 8 public: 9 void setUp(int u) { 10 up = u; 11 } 12 13 void setDown(int d) { 14 down = d; 15 } 16 17 bool stateEqual(const MagicPlate & mp) { 18 return up == mp.up && down == mp.down; 19 } 20 21 void reset() { 22 up = 1234; 23 down = 8765; 24 op = NULL; 25 pre = -1; 26 } 27 28 void operateA() { 29 int temp = up; 30 up = down; 31 down = temp; 32 33 op = 'A'; 34 } 35 36 void operateB() { 37 up = up / 10 + up % 10 * 1000; 38 down = down / 10 + down % 10 * 1000; 39 40 op = 'B'; 41 } 42 43 void operateC() { 44 int u = up % 1000 / 10; 45 int u1 = u / 10; 46 int u2 = u % 10; 47 int d = down % 1000 / 10; 48 int d1 = d / 10; 49 int d2 = d % 10; 50 51 up = up / 1000 * 1000 + d1 * 100 + u1 * 10 + up % 10; 52 down = down / 1000 * 1000 + d2 * 100 + u2 * 10 + down % 10; 53 54 op = 'C'; 55 } 56 57 void setPre(int p) { 58 pre = p; 59 } 60 61 int getPre() { 62 return pre; 63 } 64 65 char getOp() { 66 return op; 67 } 68 69 int getUp() { 70 return up; 71 } 72 73 int getDown() { 74 return down; 75 } 76 77 private: 78 int up; 79 int down; 80 char op; 81 int pre; 82 }; 83 84 85 86 vector<MagicPlate> vt; 87 set< pair<int, int> > s; 88 string opStr; 89 int fp, rp; 90 int n; 91 92 void init() { 93 opStr = ""; 94 vt.clear(); 95 s.clear(); 96 } 97 98 void getGoal(MagicPlate * mp) { 99 while (mp->getPre() != -1) { 100 opStr.push_back(mp->getOp()); 101 mp = &vt[mp->getPre()]; 102 } 103 } 104 105 bool visited(MagicPlate *mp) { 106 pair<int, int> p = pair<int, int>(mp->getUp(), mp->getDown()); 107 108 if (s.find(p) != s.end()) { 109 return true; 110 } else { 111 return false; 112 } 113 //return false; 114 /*for (int i = 0; i <= fp; i++) { 115 if (vt[i].stateEqual(mp)) { 116 return true; 117 } 118 } 119 return false;*/ 120 } 121 122 int main() { 123 while (cin >> n, n != -1) { 124 init(); 125 int temp; 126 int up = 0; 127 for (int i = 0; i < 4; i++) { 128 cin >> temp; 129 up = up * 10 + temp; 130 } 131 int down = 0; 132 for (int i = 0; i < 4; i++) { 133 cin >> temp; 134 down = down * 10 + temp; 135 } 136 MagicPlate targetMP; 137 targetMP.setUp(up); 138 targetMP.setDown(down); 139 140 MagicPlate begin; 141 begin.reset(); 142 vt.push_back(begin); 143 s.insert(pair<int, int>(begin.getUp(), begin.getDown())); 144 fp = 0; 145 rp = 1; 146 147 if (targetMP.stateEqual(begin)) { 148 cout << 0 << endl; 149 continue; 150 } 151 152 bool flag = false; 153 int step; 154 for (step = 1; step <= n; step++) { 155 int trp = rp; 156 while (fp < trp) { 157 MagicPlate mp = vt[fp]; 158 MagicPlate mpA(mp); 159 mpA.operateA(); 160 mpA.setPre(fp); 161 if (mpA.stateEqual(targetMP)) { 162 getGoal(&mpA); 163 flag = true; 164 break; 165 } else if (!visited(&mpA)) { 166 vt.push_back(mpA); 167 s.insert(pair<int, int>(mpA.getUp(), mpA.getDown())); 168 rp++; 169 } 170 171 MagicPlate mpB(mp); 172 mpB.operateB(); 173 mpB.setPre(fp); 174 if (mpB.stateEqual(targetMP)) { 175 getGoal(&mpB); 176 flag = true; 177 break; 178 } else if (!visited(&mpB)) { 179 vt.push_back(mpB); 180 s.insert(pair<int, int>(mpB.getUp(), mpB.getDown())); 181 rp++; 182 } 183 184 MagicPlate mpC(mp); 185 mpC.operateC(); 186 mpC.setPre(fp); 187 if (mpC.stateEqual(targetMP)) { 188 getGoal(&mpC); 189 flag = true; 190 break; 191 } else if (!visited(&mpC)) { 192 vt.push_back(mpC); 193 s.insert(pair<int, int>(mpC.getUp(), mpC.getDown())); 194 rp++; 195 } 196 197 fp++; 198 } 199 if (flag) break; 200 } 201 202 if (flag) { 203 cout << step << " " << string(opStr.rbegin(), opStr.rend()) << endl; 204 } else { 205 cout << -1 << endl; 206 } 207 } 208 }