【ACM】魔方十一题
0. 前言
打了两年的百度之星,都没进决赛。我最大的感受就是还是太弱,总结起来就是:人弱就要多做题,人傻就要多做题。
题目还是按照分类做可能效果比较好,因此,就有了做几个系列的计划。这是系列中的第一个,解决OJ中有关魔方的问题。
1. 概述
魔方大概会涉及两类算法:搜索和模拟。这里的搜索方式一般是双广或者bfs+剪枝,因为双广基本上就可以把题目都解了,所以我也没去
考虑A*。我自身不会玩儿魔方,因此剪枝策略也就两种,不过效果还是很好的。模拟就相对简单,仅需要了解几种旋转的方式基本上是可解。
搜索过程中存在状态爆照问题,因为对于同一个魔方从不同的角度观察得到的抽象数据类型可能不尽相同,但是状态却等价。因此,
很多题需要找到所有可能等价的状态,这其实也是一堆排列。
写魔方旋转以及等价状态,我没有什么特别好的办法。不过由给定的顺时针,可以得到相应的逆时针;由正立状态及倒立状态的映射关系,可以
仅仅通过描述正立排列迅速得到倒立状态。
魔方问题的关键就在于剪枝,双广别写萎了,以及状态等价。
2. 题目
2.1 HDOJ 4801
这是一道2阶魔方,前面做过题解,请参考【HDOJ】4801 Pocket Cube 的几种解法和优化。
2.2 HDOJ 5292
题目大意是给定任何的2阶魔方,需要判定该魔方能否复原。因为这个题目的case范围是$10^4$,所以直接在网上找的结论。具体缘由不清楚。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 5292 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <bitset> 12 #include <algorithm> 13 #include <cstdio> 14 #include <cmath> 15 #include <ctime> 16 #include <cstring> 17 #include <climits> 18 #include <cctype> 19 #include <cassert> 20 #include <functional> 21 #include <iterator> 22 #include <iomanip> 23 using namespace std; 24 #pragma comment(linker,"/STACK:102400000,1024000") 25 26 #define sti set<int> 27 #define stpii set<pair<int, int> > 28 #define mpii map<int,int> 29 #define vi vector<int> 30 #define pii pair<int,int> 31 #define vpii vector<pair<int,int> > 32 #define rep(i, a, n) for (int i=a;i<n;++i) 33 #define per(i, a, n) for (int i=n-1;i>=a;--i) 34 #define clr clear 35 #define pb push_back 36 #define mp make_pair 37 #define fir first 38 #define sec second 39 #define all(x) (x).begin(),(x).end() 40 #define SZ(x) ((int)(x).size()) 41 #define lson l, mid, rt<<1 42 #define rson mid+1, r, rt<<1|1 43 44 int a[11][11]={ 45 0,0,0,0,1,0,-1,0,0,0,0, 46 0,0,0,0,-1,0,1,0,0,0,0, 47 -1,0,1,0,0,0,0,0,-1,0,1, 48 1,0,-1,0,0,0,0,0,1,0,-1, 49 0,0,0,0,1,0,-1,0,0,0,0, 50 0,0,0,0,-1,0,1,0,0,0,0, 51 0,0,0,0,0,0,0,0,0,0,0, 52 0,0,0,0,0,0,0,0,0,0,0, 53 }; 54 55 int main() { 56 ios::sync_with_stdio(false); 57 #ifndef ONLINE_JUDGE 58 freopen("data.in", "r", stdin); 59 freopen("data.out", "w", stdout); 60 #endif 61 62 int t; 63 char op[16]; 64 65 scanf("%d", &t); 66 rep(tt, 1, t+1) { 67 getchar(); 68 int sum = 0; 69 rep(i, 0, 8) { 70 gets(op); 71 int len = strlen(op); 72 #ifndef ONLINE_JUDGE 73 puts(op); 74 #endif 75 rep(j, 0, len) { 76 if (op[j]=='y' || op[j]=='w') 77 sum += a[i][j]; 78 } 79 } 80 printf("Case #%d: ", tt); 81 puts(sum%3==0 ? "YES":"NO"); 82 } 83 84 #ifndef ONLINE_JUDGE 85 printf("time = %d.\n", (int)clock()); 86 #endif 87 88 return 0; 89 }
2.3 HDOJ 3549
同样是一道2阶魔方,求由此时情况通过一定的操作序列实现复原。找到这样一个操作序列。
这题目是很早以前解掉的,基本算法是IDA*。启发式策略是至少经过多少次旋转能实现复原,这个策略是贪心的,实际操作可能多余这个H值。
因为2阶魔方大概10几步可能就解掉了,因此这算法性能还算不错。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 3459 */ 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 6 #define MAXN 10 7 #define MAXL 1005 8 9 #define U0 map[0][2] 10 #define U1 map[0][3] 11 #define U2 map[1][3] 12 #define U3 map[1][2] 13 14 #define F0 map[2][2] 15 #define F1 map[2][3] 16 #define F2 map[3][3] 17 #define F3 map[3][2] 18 19 #define R0 map[2][4] 20 #define R1 map[2][5] 21 #define R2 map[3][5] 22 #define R3 map[3][4] 23 24 #define L0 map[2][0] 25 #define L1 map[2][1] 26 #define L2 map[3][1] 27 #define L3 map[3][0] 28 29 #define B0 map[2][6] 30 #define B1 map[2][7] 31 #define B2 map[3][7] 32 #define B3 map[3][6] 33 34 #define D0 map[4][2] 35 #define D1 map[4][3] 36 #define D2 map[5][3] 37 #define D3 map[5][2] 38 39 40 const int n = 6; 41 const int m = 8; 42 int deep; 43 char map[MAXN][MAXN]; 44 char op[MAXL]; 45 46 bool isValid() { 47 bool ret; 48 ret =\ 49 (U0==U1 && U0==U2 && U0==U3) &&\ 50 (L0==L1 && L0==L2 && L0==L3) &&\ 51 (R0==R1 && R0==R2 && R0==R3) &&\ 52 (F0==F1 && F0==F2 && F0==F3) &&\ 53 (B0==B1 && B0==B2 && B0==B3) &&\ 54 (D0==D1 && D0==D2 && D0==D3) ; 55 return ret; 56 } 57 58 void rotateX() { 59 char ch, ch1, ch2; 60 // handle right 61 ch = R0; 62 R0 = R1; 63 R1 = R2; 64 R2 = R3; 65 R3 = ch; 66 67 ch1 = F1; 68 ch2 = F2; 69 // up -> front 70 F1 = U1; 71 F2 = U2; 72 // back -> up 73 U1 = B3; 74 U2 = B0; 75 // down -> back 76 B0 = D2; 77 B3 = D1; 78 // front -> down 79 D1 = ch1; 80 D2 = ch2; 81 } 82 83 void rotateY() { 84 char ch, ch0, ch1; 85 86 // handle up 87 ch = U0; 88 U0 = U1; 89 U1 = U2; 90 U2 = U3; 91 U3 = ch; 92 93 ch0 = F0; 94 ch1 = F1; 95 // left -> front 96 F0 = L0; 97 F1 = L1; 98 // back -> left 99 L0 = B0; 100 L1 = B1; 101 // right -> back 102 B0 = R0; 103 B1 = R1; 104 // front -> right 105 R0 = ch0; 106 R1 = ch1; 107 } 108 109 void rotateZ() { 110 char ch, ch2, ch3; 111 112 // handle front 113 ch = F0; 114 F0 = F1; 115 F1 = F2; 116 F2 = F3; 117 F3 = ch; 118 119 ch2 = U2; 120 ch3 = U3; 121 // right -> up 122 U3 = R0; 123 U2 = R3; 124 // down -> right 125 R0 = D1; 126 R3 = D0; 127 // left -> down 128 D0 = L1; 129 D1 = L2; 130 // up -> left 131 L1 = ch2; 132 L2 = ch3; 133 } 134 135 int getH(){ 136 int cnt = 0; 137 if(map[2][0] != map[3][0] || map[2][7] != map[3][7]) cnt++; 138 if(map[3][6] != map[3][7] || map[5][2] != map[5][3]) cnt++; 139 if(map[4][2] != map[5][2] || map[3][0] != map[3][1]) cnt++; 140 return cnt; 141 } 142 143 bool dfs(int d) { 144 if (d+getH() > deep) 145 return false; 146 if (d == deep) 147 return isValid(); 148 149 op[d] = 'X'; 150 rotateX(); 151 if (dfs(d+1)) 152 return true; 153 rotateX(); 154 rotateX(); 155 rotateX(); 156 157 op[d] = 'Y'; 158 rotateY(); 159 if (dfs(d+1)) 160 return true; 161 rotateY(); 162 rotateY(); 163 rotateY(); 164 165 166 op[d] = 'Z'; 167 rotateZ(); 168 if (dfs(d+1)) 169 return true; 170 rotateZ(); 171 rotateZ(); 172 rotateZ(); 173 174 return false; 175 } 176 177 int main() { 178 int i, j, k; 179 180 #ifndef ONLINE_JUDGE 181 freopen("data.in", "r", stdin); 182 freopen("data.out", "w", stdout); 183 #endif 184 185 while (1) { 186 for (i=0; i<n; ++i) 187 scanf("%s", map[i]); 188 if (map[0][2] == '.') 189 break; 190 deep = 0; 191 while (1) { 192 if (dfs(0)) 193 break; 194 ++deep; 195 } 196 op[deep] = '\0'; 197 puts(op); 198 } 199 200 return 0; 201 }
2.4 HDOJ 2691
这题目当时直接拿哈希做的,其实直接转换成longlong兴许还能容易点儿。算法是双广,两种剪枝策略:任何操作的不能与它的逆操作邻接;同一种操作至多进行2次,否则一定可以使用更少操作次数的逆操作实现。这题我使用了找到任何一种魔方的等价态。不使用这个能不能过不清楚。flip函数的就是如何通过正立排列映射为倒立的排列。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2691 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <bitset> 12 #include <algorithm> 13 #include <cstdio> 14 #include <cmath> 15 #include <ctime> 16 #include <cstring> 17 #include <climits> 18 #include <cctype> 19 #include <cassert> 20 #include <functional> 21 #include <iterator> 22 #include <iomanip> 23 using namespace std; 24 #pragma comment(linker,"/STACK:102400000,1024000") 25 26 #define sti set<int> 27 #define stpii set<pair<int, int> > 28 #define mpii map<int,int> 29 #define vi vector<int> 30 #define pii pair<int,int> 31 #define vpii vector<pair<int,int> > 32 #define rep(i, a, n) for (int i=a;i<n;++i) 33 #define per(i, a, n) for (int i=n-1;i>=a;--i) 34 #define clr clear 35 #define pb push_back 36 #define mp make_pair 37 #define fir first 38 #define sec second 39 #define all(x) (x).begin(),(x).end() 40 #define SZ(x) ((int)(x).size()) 41 #define lson l, mid, rt<<1 42 #define rson mid+1, r, rt<<1|1 43 44 typedef long long LL; 45 typedef unsigned long long ULL; 46 47 typedef struct { 48 char a[24]; 49 short pre; 50 short deep; 51 52 void print() { 53 rep(i, 0, 2) putchar(' '), putchar(' '); 54 rep(i, 0, 2) putchar(a[i]), putchar(' '); 55 rep(i, 0, 2) putchar(' '), putchar(' '); 56 putchar('\n'); 57 58 rep(i, 0, 2) putchar(' '), putchar(' '); 59 rep(i, 2, 4) putchar(a[i]), putchar(' '); 60 rep(i, 0, 2) putchar(' '), putchar(' '); 61 putchar('\n'); 62 63 rep(i, 4, 10) putchar(a[i]), putchar(' '); 64 putchar('\n'); 65 rep(i, 10, 16) putchar(a[i]), putchar(' '); 66 putchar('\n'); 67 68 rep(i, 0, 2) putchar(' '), putchar(' '); 69 rep(i, 16, 18) putchar(a[i]), putchar(' '); 70 rep(i, 0, 2) putchar(' '), putchar(' '); 71 putchar('\n'); 72 73 rep(i, 0, 2) putchar(' '), putchar(' '); 74 rep(i, 18, 20) putchar(a[i]), putchar(' '); 75 rep(i, 0, 2) putchar(' '), putchar(' '); 76 putchar('\n'); 77 78 rep(i, 0, 2) putchar(' '), putchar(' '); 79 rep(i, 20, 22) putchar(a[i]), putchar(' '); 80 rep(i, 0, 2) putchar(' '), putchar(' '); 81 putchar('\n'); 82 83 rep(i, 0, 2) putchar(' '), putchar(' '); 84 rep(i, 22, 24) putchar(a[i]), putchar(' '); 85 rep(i, 0, 2) putchar(' '), putchar(' '); 86 putchar('\n'); 87 88 putchar('\n'); 89 } 90 } node_t; 91 92 int a[24], b[24]; 93 int n; 94 int face[6][4] = { 95 {0, 1, 2, 3}, 96 {4, 5, 10, 11}, 97 {6, 7, 12, 13}, 98 {8, 9, 14, 15}, 99 {16, 17, 18, 19}, 100 {20, 21, 22, 23} 101 }; 102 103 int movp[6][24] = { 104 {0,21,2,23,4,5,6,1,9,15,10,11,12,3,8,14,16,7,18,13,20,17,22,19}, 105 {0,7,2,13,4,5,6,17,14,8,10,11,12,19,15,9,16,21,18,23,20,1,22,3}, 106 {1,3,0,2,23,22,4,5,6,7,10,11,12,13,14,15,16,17,18,19,20,21,9,8}, 107 {2,0,3,1,6,7,8,9,23,22,10,11,12,13,14,15,16,17,18,19,20,21,5,4}, 108 {0,1,8,14,4,3,7,13,17,9,10,2,6,12,16,15,5,11,18,19,20,21,22,23}, 109 {0,1,11,5,4,16,12,6,2,9,10,17,13,7,3,15,14,8,18,19,20,21,22,23} 110 }; 111 int nxt[4]; 112 int unxt[4]; 113 int ans; 114 vector<node_t> vc[8]; 115 116 struct Hash { 117 static const int mod = 23456; 118 map<string,int> tb[mod]; 119 120 void clear() { 121 rep(i, 0, mod) 122 tb[i].clr(); 123 } 124 125 static int HashCode(const char *s) { 126 int ret = 0; 127 128 rep(i, 0, 24) 129 ret = (ret * 197 + s[i]) % mod; 130 131 return ret; 132 } 133 134 static LL toLL(const char *s) { 135 int ret = 0; 136 rep(i, 0, 24) ret = 10*ret + s[i]; 137 return ret; 138 } 139 140 bool find(const char* s) { 141 int h = HashCode(s); 142 return tb[h].count(string(s, 24)) > 0; 143 } 144 145 bool find(int h, const char *s) { 146 return tb[h].count(string(s, 24)) > 0; 147 } 148 149 int get(const char *s) { 150 int h = HashCode(s); 151 return tb[h][string(s, 24)]; 152 } 153 154 int get(int h, const char *s) { 155 return tb[h][string(s, 24)]; 156 } 157 158 void update(const char *s, int step) { 159 int h = HashCode(s); 160 map<string,int>& tb_ = tb[h]; 161 string ss(s, 24); 162 if (tb_.find(ss) == tb_.end()) 163 tb_[ss] = step; 164 } 165 166 void update(const char *s, int h, int step) { 167 map<string,int>& tb_ = tb[h]; 168 string ss(s, 24); 169 if (tb_.find(ss) == tb_.end()) 170 tb_[ss] = step; 171 } 172 173 }; 174 175 Hash H[2]; 176 void init_pos(); 177 178 void init() { 179 init_pos(); 180 } 181 182 vector<vi> vpos; 183 184 vi flip(const vi& vtmp) { 185 vi ret; 186 187 per(i, 16, 20) ret.pb(vtmp[i]); 188 per(i, 10, 16) ret.pb(vtmp[i]); 189 per(i, 4, 10) ret.pb(vtmp[i]); 190 per(i, 0, 4) ret.pb(vtmp[i]); 191 per(i, 20, 24) ret.pb(vtmp[i]); 192 return ret; 193 } 194 195 #define push_vtmp2(a, b) {vtmp.pb(a); vtmp.pb(b);} 196 #define push_vtmp4(a, b, c, d) {vtmp.pb(a); vtmp.pb(b); vtmp.pb(c); vtmp.pb(d);} 197 #define push_vtmp6(a, b, c, d, e, f) {vtmp.pb(a); vtmp.pb(b); vtmp.pb(c); vtmp.pb(d); vtmp.pb(e); vtmp.pb(f);} 198 void init_pos() { 199 vi vtmp; 200 201 // 1 202 vtmp.clr(); 203 push_vtmp4(0, 1, 2, 3); 204 push_vtmp6(4, 5, 6, 7, 8, 9); 205 push_vtmp6(10, 11, 12, 13, 14, 15); 206 push_vtmp4(16, 17, 18, 19); 207 push_vtmp4(20, 21, 22, 23); 208 vpos.pb(vtmp); 209 vpos.pb(flip(vtmp)); 210 211 vtmp.clr(); 212 push_vtmp4(9, 15, 8, 14); 213 push_vtmp6(1, 3, 7, 13, 17, 19); 214 push_vtmp6(0, 2, 6, 12, 16, 18); 215 push_vtmp4(5, 11, 4, 10); 216 push_vtmp4(22, 20, 23, 21); 217 vpos.pb(vtmp); 218 vpos.pb(flip(vtmp)); 219 220 221 // 2 222 vtmp.clr(); 223 push_vtmp4(1, 3, 0, 2); 224 push_vtmp6(23, 22, 4, 5, 6, 7); 225 push_vtmp6(21, 20, 10, 11, 12, 13); 226 push_vtmp4(18, 16, 19, 17); 227 push_vtmp4(15, 14, 9, 8); 228 vpos.pb(vtmp); 229 vpos.pb(flip(vtmp)); 230 231 vtmp.clr(); 232 push_vtmp4(7, 13, 6, 12); 233 push_vtmp6(3, 2, 5, 11, 16, 17); 234 push_vtmp6(1, 0, 4, 10, 18, 19); 235 push_vtmp4(22, 20, 23, 21); 236 push_vtmp4(9, 15, 8, 14); 237 vpos.pb(vtmp); 238 vpos.pb(flip(vtmp)); 239 240 // 3 241 vtmp.clr(); 242 push_vtmp4(2, 0, 3, 1); 243 push_vtmp6(6, 7, 8, 9, 23, 22); 244 push_vtmp6(12, 13, 14, 15, 21, 20); 245 push_vtmp4(17, 19, 16, 18); 246 push_vtmp4(11, 10, 5, 4); 247 vpos.pb(vtmp); 248 vpos.pb(flip(vtmp)); 249 250 vtmp.clr(); 251 push_vtmp4(12, 6, 13, 7); 252 push_vtmp6(16, 17, 14, 8, 3, 2); 253 push_vtmp6(18, 19, 15, 9, 1, 0); 254 push_vtmp4(21, 23, 20, 22); 255 push_vtmp4(10, 4, 11, 5); 256 vpos.pb(vtmp); 257 vpos.pb(flip(vtmp)); 258 259 // 4 260 vtmp.clr(); 261 push_vtmp4(3, 2, 1, 0); 262 push_vtmp6(8, 9, 23, 22, 4, 5); 263 push_vtmp6(14, 15, 21, 20, 10, 11); 264 push_vtmp4(19, 18, 17, 16); 265 push_vtmp4(13, 12, 7, 6); 266 vpos.pb(vtmp); 267 vpos.pb(flip(vtmp)); 268 269 vtmp.clr(); 270 push_vtmp4(5, 11, 4, 10); 271 push_vtmp6(2, 0, 22, 20, 18, 16); 272 push_vtmp6(3, 1, 23, 21, 19, 17); 273 push_vtmp4(9, 15, 8, 14); 274 push_vtmp4(7, 13, 6, 12); 275 vpos.pb(vtmp); 276 vpos.pb(flip(vtmp)); 277 278 // 5 279 vtmp.clr(); 280 push_vtmp4(20, 21, 22, 23); 281 push_vtmp6(10, 4, 0, 1, 9, 15); 282 push_vtmp6(11, 5, 2, 3, 8, 14); 283 push_vtmp4(6, 7, 12, 13); 284 push_vtmp4(16, 17, 18, 19); 285 vpos.pb(vtmp); 286 vpos.pb(flip(vtmp)); 287 288 vtmp.clr(); 289 push_vtmp4(15, 14, 9, 8); 290 push_vtmp6(21, 23, 1, 3, 7, 13); 291 push_vtmp6(20, 22, 0, 2, 6, 12); 292 push_vtmp4(4, 5, 10, 11); 293 push_vtmp4(18, 16, 19, 17); 294 vpos.pb(vtmp); 295 vpos.pb(flip(vtmp)); 296 297 // 6 298 vtmp.clr(); 299 push_vtmp4(6, 7, 12, 13); 300 push_vtmp6(5, 11, 16, 17, 14, 8); 301 push_vtmp6(4, 10, 18, 19, 15, 9); 302 push_vtmp4(20, 21, 22, 23); 303 push_vtmp4(0, 1, 2, 3); 304 vpos.pb(vtmp); 305 vpos.pb(flip(vtmp)); 306 307 vtmp.clr(); 308 push_vtmp4(8, 9, 14, 15); 309 push_vtmp6(7, 13, 17, 19, 21, 23); 310 push_vtmp6(6, 12, 16, 18, 20, 22); 311 push_vtmp4(11, 10, 5, 4); 312 push_vtmp4(2, 0, 3, 1); 313 vpos.pb(vtmp); 314 vpos.pb(flip(vtmp)); 315 } 316 317 node_t bnode, enode; 318 queue<node_t> Q[2]; 319 320 void Init() { 321 rep(i, 0, 2) { 322 while (!Q[i].empty()) Q[i].pop(); 323 H[i].clr(); 324 } 325 } 326 327 int update(node_t& nd, int idx, int step) { 328 static char s[26]; 329 330 Hash& h = H[idx]; 331 Hash& hh = H[idx^1]; 332 const int sz = SZ(vpos); 333 334 h.update(nd.a, step); 335 rep(i, 0, sz) { 336 rep(j, 0, 24) 337 s[j] = nd.a[vpos[i][j]]; 338 int hval = Hash::HashCode(s); 339 if (hh.find(hval, s)) 340 return step + hh.get(hval, s); 341 } 342 343 return -1; 344 } 345 346 int bfs(int idx, int step) { 347 queue<node_t>& Q = ::Q[idx]; 348 Hash& h = H[idx]; 349 int sz = SZ(Q); 350 node_t nd, d; 351 int tmp; 352 353 while (sz--) { 354 nd = Q.front(); 355 Q.pop(); 356 rep(i, 0, 6) { 357 if ((i^1) == nd.pre) 358 continue; 359 if (i != nd.pre) { 360 rep(j, 0, 24) d.a[j] = nd.a[movp[i][j]]; 361 d.pre = i; 362 d.deep = 1; 363 364 } else if (nd.deep < 2) { 365 rep(j, 0, 24) d.a[j] = nd.a[movp[i][j]]; 366 d.pre = i; 367 d.deep = 2; 368 } else { 369 continue; 370 } 371 372 if (h.find(d.a)) continue; 373 374 tmp = update(d, idx, step); 375 if (tmp >= 0) { 376 return tmp; 377 } else { 378 Q.push(d); 379 } 380 } 381 } 382 383 return -1; 384 } 385 386 void solve() { 387 Init(); 388 389 update(bnode, 0, 0); 390 if (update(enode, 1, 0) >= 0) { 391 puts("0"); 392 return ; 393 } 394 Q[0].push(bnode); 395 Q[1].push(enode); 396 397 int ans = -1, tmp; 398 399 for (int i=1; ;++i) { 400 tmp = bfs(0, i); 401 if (tmp >= 0) { 402 ans = tmp; 403 break; 404 } 405 tmp = bfs(1, i); 406 if (tmp >= 0) { 407 ans = tmp; 408 break; 409 } 410 } 411 412 printf("%d\n", ans); 413 } 414 415 int main() { 416 ios::sync_with_stdio(false); 417 #ifndef ONLINE_JUDGE 418 freopen("data.in", "r", stdin); 419 freopen("data.out", "w", stdout); 420 #endif 421 422 int t; 423 char s[24]; 424 int p[24]; 425 426 { 427 int l = 0; 428 rep(i, 0, 4) p[l++] = i; 429 rep(i, 4, 10) p[l++] = i; 430 p[l++] = 23; p[l++] = 22; 431 rep(i, 10, 16) p[l++] = i; 432 p[l++] = 21; p[l++] = 20; 433 rep(i, 16, 20) p[l++] = i; 434 } 435 436 init(); 437 scanf("%d", &t); 438 gets(s); 439 while (t--) { 440 int l = 0; 441 rep(j, 0, 6) { 442 gets(s); 443 int len = strlen(s); 444 rep(i, 0, len) { 445 if (s[i] == ' ') continue; 446 bnode.a[p[l++]] = s[i]; 447 } 448 } 449 l = 0; 450 rep(j, 0, 6) { 451 gets(s); 452 int len = strlen(s); 453 rep(i, 0, len) { 454 if (s[i] == ' ') continue; 455 enode.a[p[l++]] = s[i]; 456 } 457 } 458 bnode.pre = -1; 459 enode.pre = -1; 460 solve(); 461 } 462 463 #ifndef ONLINE_JUDGE 464 printf("time = %d.\n", (int)clock()); 465 #endif 466 467 return 0; 468 }
2.5 HDOJ 1537 && POJ 1955
这道题目杭电上做的人不多,其实就是一道模拟,难在实现3阶魔方的旋转的映射排列。题目大意是给定魔方的状态及一串操作序列,求执行完后最终的魔方状态。
其中counter表示有给定的顺时针旋转,得到互逆的逆时针旋转。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 1537 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <bitset> 12 #include <algorithm> 13 #include <cstdio> 14 #include <cmath> 15 #include <ctime> 16 #include <cstring> 17 #include <climits> 18 #include <cctype> 19 #include <cassert> 20 #include <functional> 21 #include <iterator> 22 #include <iomanip> 23 using namespace std; 24 //#pragma comment(linker,"/STACK:102400000,1024000") 25 26 #define sti set<int> 27 #define stpii set<pair<int, int> > 28 #define mpii map<int,int> 29 #define vi vector<int> 30 #define pii pair<int,int> 31 #define vpii vector<pair<int,int> > 32 #define rep(i, a, n) for (int i=a;i<n;++i) 33 #define per(i, a, n) for (int i=n-1;i>=a;--i) 34 #define clr clear 35 #define pb push_back 36 #define mp make_pair 37 #define fir first 38 #define sec second 39 #define all(x) (x).begin(),(x).end() 40 #define SZ(x) ((int)(x).size()) 41 #define lson l, mid, rt<<1 42 #define rson mid+1, r, rt<<1|1 43 44 #define LEFT 0 45 #define FRONT 1 46 #define RIGHT 2 47 #define BACK 3 48 #define TOP 4 49 #define BOTTOM 5 50 int face[6][9] = { 51 /*Left*/ {9, 10, 11, 21, 22, 23, 33, 34, 35}, 52 /*Front*/ {12, 13, 14, 24, 25, 26, 36, 37, 38}, 53 /*Right*/ {15, 16, 17, 27, 28, 29, 39, 40, 41}, 54 /*Back*/ {18, 19, 20, 30, 31, 32, 42, 43, 44}, 55 /*Top*/ {0, 1, 2, 3, 4, 5, 6, 7, 8}, 56 /*Bottom*/ {45, 46, 47, 48, 49, 50, 51, 52, 53} 57 }; 58 59 char s[56], d[56]; 60 int q; 61 vector<vi> vpos; 62 63 vi counter(const vi& p) { 64 int a[56], b[56]; 65 66 rep(i, 0, 54) a[i] = i; 67 rep(i, 0, 3) { 68 rep(j, 0, 54) b[j] = a[p[j]]; 69 memcpy(a, b, sizeof(b)); 70 } 71 72 return vi(a, a+54); 73 } 74 75 void init() { 76 int a[56], b[56]; 77 78 #define MOVE_ROW(des, src)\ 79 {\ 80 rep(i, 0, 3)\ 81 b[face[des][i]] = a[face[src][i]];\ 82 } 83 84 #define MOVE_ROW_(des, src)\ 85 {\ 86 rep(i, 6, 9)\ 87 b[face[des][i]] = a[face[src][i]];\ 88 } 89 90 #define MOVE_COL(des, src)\ 91 {\ 92 rep(i, 0, 3)\ 93 b[face[des][i*3]] = a[face[src][i*3]];\ 94 } 95 #define FORCE_MOVE(da, sa, db, sb, dc, sc)\ 96 {\ 97 b[da] = a[sa];\ 98 b[db] = a[sb];\ 99 b[dc] = a[sc];\ 100 } 101 102 103 // rotate LEFT 104 { 105 rep(i, 0, 54) a[i] = i; 106 107 memcpy(b, a, sizeof(a)); 108 int* mf = face[LEFT]; 109 rep(i, 0, 3) { 110 rep(j, 0, 3) { 111 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 112 } 113 } 114 MOVE_COL(FRONT, TOP); 115 MOVE_COL(BOTTOM, FRONT); 116 FORCE_MOVE(20, 51, 32, 48, 44, 45); //MOVE_COL(BACK, BOTTOM); 117 FORCE_MOVE(0, 44, 3, 32, 6, 20); // MOVE_COL(TOP, BACK); 118 119 vi vtmp(b, b+54); 120 vpos.pb(vtmp); 121 vpos.pb(counter(vtmp)); 122 } 123 124 // rotate FRONT 125 { 126 rep(i, 0, 54) a[i] = i; 127 128 memcpy(b, a, sizeof(a)); 129 int* mf = face[FRONT]; 130 rep(i, 0, 3) { 131 rep(j, 0, 3) { 132 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 133 } 134 } 135 FORCE_MOVE(face[TOP][6], face[LEFT][8], face[TOP][7], face[LEFT][5], face[TOP][8], face[LEFT][2]); // MOVE_COL(TOP, LEFT); 136 FORCE_MOVE(face[RIGHT][0], face[TOP][6], face[RIGHT][3], face[TOP][7], face[RIGHT][6], face[TOP][8]); // MOVE_COL(RIGHT, TOP); 137 FORCE_MOVE(face[BOTTOM][0], face[RIGHT][6], face[BOTTOM][1], face[RIGHT][3], face[BOTTOM][2], face[RIGHT][0]); // MOVE_COL(BOTTOM, RIGHT); 138 FORCE_MOVE(face[LEFT][2], face[BOTTOM][0], face[LEFT][5], face[BOTTOM][1], face[LEFT][8], face[BOTTOM][2]); // MOVE_COL(LEFT, BOTTOM); 139 140 vi vtmp(b, b+54); 141 vpos.pb(vtmp); 142 vpos.pb(counter(vtmp)); 143 } 144 145 // rotate RIGHT 146 { 147 rep(i, 0, 54) a[i] = i; 148 149 memcpy(b, a, sizeof(a)); 150 int* mf = face[RIGHT]; 151 rep(i, 0, 3) { 152 rep(j, 0, 3) { 153 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 154 } 155 } 156 FORCE_MOVE(face[TOP][2], face[FRONT][2], face[TOP][5], face[FRONT][5], face[TOP][8], face[FRONT][8]); // MOVE_COL(TOP, FRONT); 157 FORCE_MOVE(face[FRONT][2], face[BOTTOM][2], face[FRONT][5], face[BOTTOM][5], face[FRONT][8], face[BOTTOM][8]); // MOVE_COL(FRONT, BOTTOM); 158 FORCE_MOVE(face[BOTTOM][2], 42, face[BOTTOM][5], 30, face[BOTTOM][8], 18); // MOVE_COL(BOTTOM, BACK); 159 FORCE_MOVE(42, 2, 30, 5, 18, 8); // MOVE_COL(BACK, TOP); 160 161 vi vtmp(b, b+54); 162 vpos.pb(vtmp); 163 vpos.pb(counter(vtmp)); 164 } 165 166 // rotate BACK 167 { 168 rep(i, 0, 54) a[i] = i; 169 170 memcpy(b, a, sizeof(a)); 171 int* mf = face[BACK]; 172 rep(i, 0, 3) { 173 rep(j, 0, 3) { 174 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 175 } 176 } 177 FORCE_MOVE(face[LEFT][0], face[TOP][2], face[LEFT][3], face[TOP][1], face[LEFT][6], face[TOP][0]); // MOVE(LEFT, TOP); 178 FORCE_MOVE(face[TOP][0], face[RIGHT][2], face[TOP][1], face[RIGHT][5], face[TOP][2], face[RIGHT][8]); // MOVE(TOP, RIGHT); 179 FORCE_MOVE(face[RIGHT][2], 53, face[RIGHT][5], 52, face[RIGHT][8], 51); // MOVE(RIGHT, BOTTOM); 180 FORCE_MOVE(53, face[LEFT][6], 52, face[LEFT][3], 51, face[LEFT][0]); // MOVE(BOTTOM, LEFT); 181 182 vi vtmp(b, b+54); 183 vpos.pb(vtmp); 184 vpos.pb(counter(vtmp)); 185 } 186 187 // rotate Top 188 { 189 190 rep(i, 0, 54) a[i] = i; 191 192 memcpy(b, a, sizeof(a)); 193 int* mf = face[TOP]; 194 rep(i, 0, 3) { 195 rep(j, 0, 3) { 196 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 197 } 198 } 199 MOVE_ROW(LEFT, FRONT); 200 MOVE_ROW(FRONT, RIGHT); 201 MOVE_ROW(RIGHT, BACK); 202 MOVE_ROW(BACK, LEFT); 203 204 vi vtmp(b, b+54); 205 vpos.pb(vtmp); 206 vpos.pb(counter(vtmp)); 207 } 208 209 // rotate BOTTOM 210 { 211 rep(i, 0, 54) a[i] = i; 212 213 memcpy(b, a, sizeof(a)); 214 int* mf = face[BOTTOM]; 215 rep(i, 0, 3) { 216 rep(j, 0, 3) { 217 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 218 } 219 } 220 MOVE_ROW_(FRONT, LEFT); 221 MOVE_ROW_(RIGHT, FRONT); 222 MOVE_ROW_(BACK, RIGHT); 223 MOVE_ROW_(LEFT, BACK); 224 225 vi vtmp(b, b+54); 226 vpos.pb(vtmp); 227 vpos.pb(counter(vtmp)); 228 } 229 } 230 231 void rotate(int f, int dir) { 232 int idx = f * 2; 233 if (dir == -1) idx += 1; 234 memcpy(d, s, sizeof(d)); 235 vi& p = vpos[idx]; 236 #ifndef ONLINE_JUDGE 237 assert(idx>=0 && idx<SZ(p)); 238 #endif 239 rep(i, 0, 54) s[i] = d[p[i]]; 240 } 241 242 void printAns(char *s) { 243 int idx = 0; 244 245 rep(i, 0, 3) { 246 printf(" "); 247 rep(j, 0, 3) { 248 putchar(' '); 249 putchar(s[idx++]); 250 } 251 putchar('\n'); 252 } 253 254 rep(i, 0, 3) { 255 rep(j, 0, 12) { 256 if (j) putchar(' '); 257 putchar(s[idx++]); 258 } 259 putchar('\n'); 260 } 261 262 rep(i, 0, 3) { 263 printf(" "); 264 rep(j, 0, 3) { 265 putchar(' '); 266 putchar(s[idx++]); 267 } 268 putchar('\n'); 269 } 270 } 271 272 void solve() { 273 int f, d; 274 275 while (q--) { 276 scanf("%d%d", &f, &d); 277 rotate(f, d); 278 } 279 printAns(s); 280 } 281 282 int main() { 283 cin.tie(0); 284 ios::sync_with_stdio(false); 285 #ifndef ONLINE_JUDGE 286 freopen("data.in", "r", stdin); 287 freopen("data.out", "w", stdout); 288 #endif 289 290 int t; 291 char op[4]; 292 293 init(); 294 scanf("%d", &t); 295 rep(tt, 1, t+1) { 296 rep(i, 0, 54) { 297 scanf("%s", op); 298 s[i] = op[0]; 299 } 300 scanf("%d", &q); 301 printf("Scenario #%d:\n", tt); 302 solve(); 303 putchar('\n'); 304 } 305 306 #ifndef ONLINE_JUDGE 307 printf("time = %ldms.\n", clock()); 308 #endif 309 310 return 0; 311 }
2.6 HDOJ 2168
写完了上一道题,这道题也基本写完了,重新映射一下输入的三阶魔方以及输出结果。这题就直接过了。注意这道题没有逆时针旋转。题目数据非常弱,完全不用优化。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2168 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <bitset> 12 #include <algorithm> 13 #include <cstdio> 14 #include <cmath> 15 #include <ctime> 16 #include <cstring> 17 #include <climits> 18 #include <cctype> 19 #include <cassert> 20 #include <functional> 21 #include <iterator> 22 #include <iomanip> 23 using namespace std; 24 //#pragma comment(linker,"/STACK:102400000,1024000") 25 26 #define sti set<int> 27 #define stpii set<pair<int, int> > 28 #define mpii map<int,int> 29 #define vi vector<int> 30 #define pii pair<int,int> 31 #define vpii vector<pair<int,int> > 32 #define rep(i, a, n) for (int i=a;i<n;++i) 33 #define per(i, a, n) for (int i=n-1;i>=a;--i) 34 #define clr clear 35 #define pb push_back 36 #define mp make_pair 37 #define fir first 38 #define sec second 39 #define all(x) (x).begin(),(x).end() 40 #define SZ(x) ((int)(x).size()) 41 #define lson l, mid, rt<<1 42 #define rson mid+1, r, rt<<1|1 43 44 #define LEFT 0 45 #define FRONT 1 46 #define RIGHT 2 47 #define BACK 3 48 #define TOP 4 49 #define BOTTOM 5 50 int face[6][9] = { 51 /*Left*/ {9, 10, 11, 21, 22, 23, 33, 34, 35}, 52 /*Front*/ {12, 13, 14, 24, 25, 26, 36, 37, 38}, 53 /*Right*/ {15, 16, 17, 27, 28, 29, 39, 40, 41}, 54 /*Back*/ {18, 19, 20, 30, 31, 32, 42, 43, 44}, 55 /*Top*/ {0, 1, 2, 3, 4, 5, 6, 7, 8}, 56 /*Bottom*/ {45, 46, 47, 48, 49, 50, 51, 52, 53} 57 }; 58 59 const int maxl = 1015; 60 char ops[maxl]; 61 char s[56], d[56]; 62 int q; 63 vector<vi> vpos; 64 int ipos[54], ipos_[54]; 65 66 vi counter(const vi& p) { 67 int a[56], b[56]; 68 69 rep(i, 0, 54) a[i] = i; 70 rep(i, 0, 3) { 71 rep(j, 0, 54) b[j] = a[p[j]]; 72 memcpy(a, b, sizeof(b)); 73 } 74 75 return vi(a, a+54); 76 } 77 78 void init() { 79 int a[56], b[56]; 80 81 #define MOVE_ROW(des, src)\ 82 {\ 83 rep(i, 0, 3)\ 84 b[face[des][i]] = a[face[src][i]];\ 85 } 86 87 #define MOVE_ROW_(des, src)\ 88 {\ 89 rep(i, 6, 9)\ 90 b[face[des][i]] = a[face[src][i]];\ 91 } 92 93 #define MOVE_COL(des, src)\ 94 {\ 95 rep(i, 0, 3)\ 96 b[face[des][i*3]] = a[face[src][i*3]];\ 97 } 98 #define FORCE_MOVE(da, sa, db, sb, dc, sc)\ 99 {\ 100 b[da] = a[sa];\ 101 b[db] = a[sb];\ 102 b[dc] = a[sc];\ 103 } 104 105 106 // rotate U 107 { 108 109 rep(i, 0, 54) a[i] = i; 110 111 memcpy(b, a, sizeof(a)); 112 int* mf = face[TOP]; 113 rep(i, 0, 3) { 114 rep(j, 0, 3) { 115 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 116 } 117 } 118 MOVE_ROW(LEFT, FRONT); 119 MOVE_ROW(FRONT, RIGHT); 120 MOVE_ROW(RIGHT, BACK); 121 MOVE_ROW(BACK, LEFT); 122 123 vi vtmp(b, b+54); 124 vpos.pb(vtmp); 125 } 126 127 // rotate R 128 { 129 rep(i, 0, 54) a[i] = i; 130 131 memcpy(b, a, sizeof(a)); 132 int* mf = face[RIGHT]; 133 rep(i, 0, 3) { 134 rep(j, 0, 3) { 135 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 136 } 137 } 138 FORCE_MOVE(face[TOP][2], face[FRONT][2], face[TOP][5], face[FRONT][5], face[TOP][8], face[FRONT][8]); // MOVE_COL(TOP, FRONT); 139 FORCE_MOVE(face[FRONT][2], face[BOTTOM][2], face[FRONT][5], face[BOTTOM][5], face[FRONT][8], face[BOTTOM][8]); // MOVE_COL(FRONT, BOTTOM); 140 FORCE_MOVE(face[BOTTOM][2], 42, face[BOTTOM][5], 30, face[BOTTOM][8], 18); // MOVE_COL(BOTTOM, BACK); 141 FORCE_MOVE(42, 2, 30, 5, 18, 8); // MOVE_COL(BACK, TOP); 142 143 vi vtmp(b, b+54); 144 vpos.pb(vtmp); 145 } 146 147 // rotate F 148 { 149 rep(i, 0, 54) a[i] = i; 150 151 memcpy(b, a, sizeof(a)); 152 int* mf = face[FRONT]; 153 rep(i, 0, 3) { 154 rep(j, 0, 3) { 155 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 156 } 157 } 158 FORCE_MOVE(face[TOP][6], face[LEFT][8], face[TOP][7], face[LEFT][5], face[TOP][8], face[LEFT][2]); // MOVE_COL(TOP, LEFT); 159 FORCE_MOVE(face[RIGHT][0], face[TOP][6], face[RIGHT][3], face[TOP][7], face[RIGHT][6], face[TOP][8]); // MOVE_COL(RIGHT, TOP); 160 FORCE_MOVE(face[BOTTOM][0], face[RIGHT][6], face[BOTTOM][1], face[RIGHT][3], face[BOTTOM][2], face[RIGHT][0]); // MOVE_COL(BOTTOM, RIGHT); 161 FORCE_MOVE(face[LEFT][2], face[BOTTOM][0], face[LEFT][5], face[BOTTOM][1], face[LEFT][8], face[BOTTOM][2]); // MOVE_COL(LEFT, BOTTOM); 162 163 vi vtmp(b, b+54); 164 vpos.pb(vtmp); 165 } 166 167 // rotate D 168 { 169 rep(i, 0, 54) a[i] = i; 170 171 memcpy(b, a, sizeof(a)); 172 int* mf = face[BOTTOM]; 173 rep(i, 0, 3) { 174 rep(j, 0, 3) { 175 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 176 } 177 } 178 MOVE_ROW_(FRONT, LEFT); 179 MOVE_ROW_(RIGHT, FRONT); 180 MOVE_ROW_(BACK, RIGHT); 181 MOVE_ROW_(LEFT, BACK); 182 183 vi vtmp(b, b+54); 184 vpos.pb(vtmp); 185 } 186 187 // rotate L 188 { 189 rep(i, 0, 54) a[i] = i; 190 191 memcpy(b, a, sizeof(a)); 192 int* mf = face[LEFT]; 193 rep(i, 0, 3) { 194 rep(j, 0, 3) { 195 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 196 } 197 } 198 MOVE_COL(FRONT, TOP); 199 MOVE_COL(BOTTOM, FRONT); 200 FORCE_MOVE(20, 51, 32, 48, 44, 45); //MOVE_COL(BACK, BOTTOM); 201 FORCE_MOVE(0, 44, 3, 32, 6, 20); // MOVE_COL(TOP, BACK); 202 203 vi vtmp(b, b+54); 204 vpos.pb(vtmp); 205 } 206 207 // rotate B 208 { 209 rep(i, 0, 54) a[i] = i; 210 211 memcpy(b, a, sizeof(a)); 212 int* mf = face[BACK]; 213 rep(i, 0, 3) { 214 rep(j, 0, 3) { 215 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 216 } 217 } 218 FORCE_MOVE(face[LEFT][0], face[TOP][2], face[LEFT][3], face[TOP][1], face[LEFT][6], face[TOP][0]); // MOVE(LEFT, TOP); 219 FORCE_MOVE(face[TOP][0], face[RIGHT][2], face[TOP][1], face[RIGHT][5], face[TOP][2], face[RIGHT][8]); // MOVE(TOP, RIGHT); 220 FORCE_MOVE(face[RIGHT][2], 53, face[RIGHT][5], 52, face[RIGHT][8], 51); // MOVE(RIGHT, BOTTOM); 221 FORCE_MOVE(53, face[LEFT][6], 52, face[LEFT][3], 51, face[LEFT][0]); // MOVE(BOTTOM, LEFT); 222 223 vi vtmp(b, b+54); 224 vpos.pb(vtmp); 225 } 226 227 #ifndef ONLINE_JUDGE 228 assert(SZ(vpos) == 6); 229 memset(ipos, -1, sizeof(ipos)); 230 memset(ipos_, -1, sizeof(ipos_)); 231 #endif 232 { 233 int base; 234 235 base = 0; 236 rep(i, 0, 3) { 237 rep(j, 0, 3) { 238 ipos[face[LEFT][i*3+j]] = base + j; 239 } 240 base += 18; 241 } 242 243 base = 3; 244 rep(i, 0, 3) { 245 rep(j, 0, 3) { 246 ipos[face[FRONT][i*3+j]] = base + j; 247 } 248 base += 18; 249 } 250 251 base = 6; 252 rep(i, 0, 3) { 253 rep(j, 0, 3) { 254 ipos[face[BOTTOM][i*3+j]] = base + j; 255 } 256 base += 18; 257 } 258 259 base = 9; 260 rep(i, 0, 3) { 261 rep(j, 0, 3) { 262 ipos[face[BACK][(2-i)*3+(2-j)]] = base + j; 263 } 264 base += 18; 265 } 266 267 base = 12; 268 rep(i, 0, 3) { 269 rep(j, 0, 3) { 270 ipos[face[TOP][i*3+j]] = base + j; 271 } 272 base += 18; 273 } 274 275 base = 15; 276 rep(i, 0, 3) { 277 rep(j, 0, 3) { 278 ipos[face[RIGHT][j*3+2-i]] = base + j; 279 } 280 base += 18; 281 } 282 283 rep(i, 0, 54) { 284 ipos_[ipos[i]] = i; 285 } 286 } 287 } 288 289 void rotate(char c1) { 290 static char uc[] = "GYORWB"; 291 292 int idx = strchr(uc, c1) - uc; 293 294 memcpy(d, s, sizeof(d)); 295 rep(j, 0, 54) 296 s[j] = d[vpos[idx][j]]; 297 } 298 299 void printAns() { 300 rep(i, 0, 54) d[i] = s[ipos_[i]]; 301 rep(i, 0, 54) { 302 if (i==17 || i==35 || i==53) { 303 putchar(d[i]); 304 putchar('\n'); 305 } else { 306 putchar(d[i]); 307 putchar(' '); 308 } 309 } 310 } 311 312 void solve() { 313 int len = strlen(ops); 314 315 rep(i, 0, 54) s[i] = d[ipos[i]]; 316 rep(i, 0, len) { 317 rotate(ops[i]); 318 } 319 320 printAns(); 321 } 322 323 int main() { 324 cin.tie(0); 325 ios::sync_with_stdio(false); 326 #ifndef ONLINE_JUDGE 327 freopen("data.in", "r", stdin); 328 freopen("data.out", "w", stdout); 329 #endif 330 331 int t; 332 char op[4]; 333 334 init(); 335 scanf("%d", &t); 336 while (t--) { 337 rep(i, 0, 54) { 338 scanf("%s", op); 339 d[i] = op[0]; 340 } 341 scanf("%s", ops); 342 solve(); 343 puts("==================================="); 344 } 345 346 #ifndef ONLINE_JUDGE 347 printf("time = %ldms.\n", clock()); 348 #endif 349 350 return 0; 351 }
2.7 HDOJ 2953
这题是个2阶魔方,但是比前面的题目难,难点在于需要对初始魔方进行一个映射。题目是需要是讲魔方复原。但是每个面的颜色存在着不同的组合,这也导致最终魔方的状态不等价。
重新映射后就可以利用预处理的结果了,过预处理的由结束状态魔方执行7步操作可达状态。如果不在预处理状态中,那么bfs找到最优解。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2953 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <bitset> 12 #include <algorithm> 13 #include <cstdio> 14 #include <cmath> 15 #include <ctime> 16 #include <cstring> 17 #include <climits> 18 #include <cctype> 19 #include <cassert> 20 #include <functional> 21 #include <iterator> 22 #include <iomanip> 23 using namespace std; 24 #pragma comment(linker,"/STACK:102400000,1024000") 25 26 #define sti set<int> 27 #define stpii set<pair<int, int> > 28 #define mpii map<int,int> 29 #define vi vector<int> 30 #define pii pair<int,int> 31 #define vpii vector<pair<int,int> > 32 #define rep(i, a, n) for (int i=a;i<n;++i) 33 #define per(i, a, n) for (int i=n-1;i>=a;--i) 34 #define clr clear 35 #define pb push_back 36 #define mp make_pair 37 #define fir first 38 #define sec second 39 #define all(x) (x).begin(),(x).end() 40 #define SZ(x) ((int)(x).size()) 41 #define lson l, mid, rt<<1 42 #define rson mid+1, r, rt<<1|1 43 44 typedef long long LL; 45 typedef unsigned long long ULL; 46 typedef struct { 47 char a[24]; 48 int pre, deep; 49 } node_t; 50 51 int a[24]; 52 char s[24]; 53 int face[6][4] = { 54 {0, 1, 2, 3}, 55 {4, 5, 10, 11}, 56 {6, 7, 12, 13}, 57 {8, 9, 14, 15}, 58 {16, 17, 18, 19}, 59 {20, 21, 22, 23} 60 }; 61 int movp[6][24] = { 62 {0,21,2,23,4,5,6,1,9,15,10,11,12,3,8,14,16,7,18,13,20,17,22,19}, 63 {0,7,2,13,4,5,6,17,14,8,10,11,12,19,15,9,16,21,18,23,20,1,22,3}, 64 {1,3,0,2,23,22,4,5,6,7,10,11,12,13,14,15,16,17,18,19,20,21,9,8}, 65 {2,0,3,1,6,7,8,9,23,22,10,11,12,13,14,15,16,17,18,19,20,21,5,4}, 66 {0,1,8,14,4,3,7,13,17,9,10,2,6,12,16,15,5,11,18,19,20,21,22,23}, 67 {0,1,11,5,4,16,12,6,2,9,10,17,13,7,3,15,14,8,18,19,20,21,22,23} 68 }; 69 70 ULL HashCode(const char *s) { 71 ULL ret = 0; 72 73 rep(i, 0, 24) 74 ret = ret * 6 + s[i]; 75 76 return ret; 77 } 78 79 vector<vi> vpos; 80 81 struct Hash { 82 map<ULL,int> tb; 83 map<ULL,int>::iterator iter; 84 85 void clear() { 86 tb.clr(); 87 } 88 89 int find(const char *b) { 90 const int sz = SZ(vpos); 91 static char a[24]; 92 93 rep(i, 0, sz) { 94 rep(j, 0, 24) 95 a[j] = b[vpos[i][j]]; 96 ULL h = HashCode(a); 97 iter = tb.find(h); 98 if (iter != tb.end()) return iter->sec; 99 } 100 101 return -1; 102 } 103 104 bool update(const char *b, int step) { 105 const int sz = SZ(vpos); 106 static char a[24]; 107 108 rep(i, 0, sz) { 109 rep(j, 0, 24) 110 a[j] = b[vpos[i][j]]; 111 ULL h = HashCode(a); 112 if (tb.count(h) > 0) return true; 113 } 114 115 ULL h = HashCode(b); 116 tb[h] = step; 117 return false; 118 } 119 }; 120 121 Hash H, HH; 122 123 vi flip(const vi& vtmp) { 124 vi ret; 125 126 per(i, 16, 20) ret.pb(vtmp[i]); 127 per(i, 10, 16) ret.pb(vtmp[i]); 128 per(i, 4, 10) ret.pb(vtmp[i]); 129 per(i, 0, 4) ret.pb(vtmp[i]); 130 per(i, 20, 24) ret.pb(vtmp[i]); 131 return ret; 132 } 133 134 #define push_vtmp2(a, b) {vtmp.pb(a); vtmp.pb(b);} 135 #define push_vtmp4(a, b, c, d) {vtmp.pb(a); vtmp.pb(b); vtmp.pb(c); vtmp.pb(d);} 136 #define push_vtmp6(a, b, c, d, e, f) {vtmp.pb(a); vtmp.pb(b); vtmp.pb(c); vtmp.pb(d); vtmp.pb(e); vtmp.pb(f);} 137 void init_pos() { 138 vi vtmp; 139 140 // 1 141 vtmp.clr(); 142 push_vtmp4(0, 1, 2, 3); 143 push_vtmp6(4, 5, 6, 7, 8, 9); 144 push_vtmp6(10, 11, 12, 13, 14, 15); 145 push_vtmp4(16, 17, 18, 19); 146 push_vtmp4(20, 21, 22, 23); 147 vpos.pb(vtmp); 148 vpos.pb(flip(vtmp)); 149 150 vtmp.clr(); 151 push_vtmp4(9, 15, 8, 14); 152 push_vtmp6(1, 3, 7, 13, 17, 19); 153 push_vtmp6(0, 2, 6, 12, 16, 18); 154 push_vtmp4(5, 11, 4, 10); 155 push_vtmp4(22, 20, 23, 21); 156 vpos.pb(vtmp); 157 vpos.pb(flip(vtmp)); 158 159 160 // 2 161 vtmp.clr(); 162 push_vtmp4(1, 3, 0, 2); 163 push_vtmp6(23, 22, 4, 5, 6, 7); 164 push_vtmp6(21, 20, 10, 11, 12, 13); 165 push_vtmp4(18, 16, 19, 17); 166 push_vtmp4(15, 14, 9, 8); 167 vpos.pb(vtmp); 168 vpos.pb(flip(vtmp)); 169 170 vtmp.clr(); 171 push_vtmp4(7, 13, 6, 12); 172 push_vtmp6(3, 2, 5, 11, 16, 17); 173 push_vtmp6(1, 0, 4, 10, 18, 19); 174 push_vtmp4(22, 20, 23, 21); 175 push_vtmp4(9, 15, 8, 14); 176 vpos.pb(vtmp); 177 vpos.pb(flip(vtmp)); 178 179 // 3 180 vtmp.clr(); 181 push_vtmp4(2, 0, 3, 1); 182 push_vtmp6(6, 7, 8, 9, 23, 22); 183 push_vtmp6(12, 13, 14, 15, 21, 20); 184 push_vtmp4(17, 19, 16, 18); 185 push_vtmp4(11, 10, 5, 4); 186 vpos.pb(vtmp); 187 vpos.pb(flip(vtmp)); 188 189 vtmp.clr(); 190 push_vtmp4(12, 6, 13, 7); 191 push_vtmp6(16, 17, 14, 8, 3, 2); 192 push_vtmp6(18, 19, 15, 9, 1, 0); 193 push_vtmp4(21, 23, 20, 22); 194 push_vtmp4(10, 4, 11, 5); 195 vpos.pb(vtmp); 196 vpos.pb(flip(vtmp)); 197 198 // 4 199 vtmp.clr(); 200 push_vtmp4(3, 2, 1, 0); 201 push_vtmp6(8, 9, 23, 22, 4, 5); 202 push_vtmp6(14, 15, 21, 20, 10, 11); 203 push_vtmp4(19, 18, 17, 16); 204 push_vtmp4(13, 12, 7, 6); 205 vpos.pb(vtmp); 206 vpos.pb(flip(vtmp)); 207 208 vtmp.clr(); 209 push_vtmp4(5, 11, 4, 10); 210 push_vtmp6(2, 0, 22, 20, 18, 16); 211 push_vtmp6(3, 1, 23, 21, 19, 17); 212 push_vtmp4(9, 15, 8, 14); 213 push_vtmp4(7, 13, 6, 12); 214 vpos.pb(vtmp); 215 vpos.pb(flip(vtmp)); 216 217 // 5 218 vtmp.clr(); 219 push_vtmp4(20, 21, 22, 23); 220 push_vtmp6(10, 4, 0, 1, 9, 15); 221 push_vtmp6(11, 5, 2, 3, 8, 14); 222 push_vtmp4(6, 7, 12, 13); 223 push_vtmp4(16, 17, 18, 19); 224 vpos.pb(vtmp); 225 vpos.pb(flip(vtmp)); 226 227 vtmp.clr(); 228 push_vtmp4(15, 14, 9, 8); 229 push_vtmp6(21, 23, 1, 3, 7, 13); 230 push_vtmp6(20, 22, 0, 2, 6, 12); 231 push_vtmp4(4, 5, 10, 11); 232 push_vtmp4(18, 16, 19, 17); 233 vpos.pb(vtmp); 234 vpos.pb(flip(vtmp)); 235 236 // 6 237 vtmp.clr(); 238 push_vtmp4(6, 7, 12, 13); 239 push_vtmp6(5, 11, 16, 17, 14, 8); 240 push_vtmp6(4, 10, 18, 19, 15, 9); 241 push_vtmp4(20, 21, 22, 23); 242 push_vtmp4(0, 1, 2, 3); 243 vpos.pb(vtmp); 244 vpos.pb(flip(vtmp)); 245 246 vtmp.clr(); 247 push_vtmp4(8, 9, 14, 15); 248 push_vtmp6(7, 13, 17, 19, 21, 23); 249 push_vtmp6(6, 12, 16, 18, 20, 22); 250 push_vtmp4(11, 10, 5, 4); 251 push_vtmp4(2, 0, 3, 1); 252 vpos.pb(vtmp); 253 vpos.pb(flip(vtmp)); 254 } 255 256 257 void init_bfs() { 258 queue<node_t> Q; 259 node_t nd, d; 260 261 rep(i, 0, 6) 262 rep(j, 0, 4) 263 nd.a[face[i][j]] = i; 264 nd.pre = -1; 265 nd.deep = 0; 266 Q.push(nd); 267 268 H.update(nd.a, 0); 269 for (int step=1; step<=7; ++step) { 270 int sz = SZ(Q); 271 while (sz--) { 272 nd = Q.front(); 273 Q.pop(); 274 rep(i, 0, 6) { 275 if ((i^1) == nd.pre) 276 continue; 277 if (i != nd.pre) { 278 rep(j, 0, 24) d.a[j] = nd.a[movp[i][j]]; 279 d.pre = i; 280 d.deep = 1; 281 282 } else if (nd.deep < 2) { 283 rep(j, 0, 24) d.a[j] = nd.a[movp[i][j]]; 284 d.pre = i; 285 d.deep = 2; 286 } else { 287 continue; 288 } 289 290 if (!H.update(d.a, step)) { 291 Q.push(d); 292 } 293 } 294 } 295 } 296 } 297 298 void init() { 299 init_pos(); 300 init_bfs(); 301 } 302 303 int bfs() { 304 int step = 0; 305 queue<node_t> Q; 306 node_t nd, d; 307 308 rep(i, 0, 24) nd.a[i] = a[i]; 309 nd.pre = -1; 310 nd.deep = 0; 311 Q.push(nd); 312 313 HH.update(nd.a, 0); 314 315 while (1) { 316 int sz = SZ(Q); 317 if (sz == 0) break; 318 ++step; 319 while (sz--) { 320 nd = Q.front(); 321 Q.pop(); 322 rep(i, 0, 6) { 323 if ((i^1) == nd.pre) 324 continue; 325 if (i != nd.pre) { 326 rep(j, 0, 24) d.a[j] = nd.a[movp[i][j]]; 327 d.pre = i; 328 d.deep = 1; 329 330 } else if (nd.deep < 2) { 331 rep(j, 0, 24) d.a[j] = nd.a[movp[i][j]]; 332 d.pre = i; 333 d.deep = 2; 334 } else { 335 continue; 336 } 337 338 if (!HH.update(d.a, step)) { 339 int tmp = H.find(d.a); 340 if (tmp >= 0) return step + tmp; 341 Q.push(d); 342 } 343 } 344 } 345 } 346 347 return -1; 348 } 349 350 void solve() { 351 static char b[24]; 352 rep(j, 0, 24) b[j] = a[j]; 353 int ans = H.find(b); 354 355 if (ans >= 0) { 356 printf("%d\n", ans); 357 return ; 358 } 359 360 ans = bfs(); 361 printf("%d\n", ans); 362 } 363 364 inline int getVal(char c) { 365 if (c == 'O') return 0; 366 if (c == 'W') return 1; 367 if (c == 'R') return 2; 368 if (c == 'G') return 3; 369 if (c == 'Y') return 4; 370 if (c == 'B') return 5; 371 return -1; 372 } 373 374 void transfer() { 375 static int block[8][3]={ 376 {3,5,6}, {1,7,8}, {0,9,10}, {2,4,11}, 377 {12,19,20}, {13,14,21}, {15,16,23}, {17,18,22} 378 }; 379 map<char,char> col; 380 map<char,bool> flag; 381 col[s[17]] = 'B'; 382 flag[s[17]] = true; 383 col[s[18]] = 'W'; 384 flag[s[18]] = true; 385 col[s[22]] = 'Y'; 386 flag[s[22]] = true; 387 rep(i, 0, 7) { 388 int cnt = 0, sum = 0, has = 3; 389 if(flag[s[block[i][0]]]) { 390 ++cnt; 391 sum += col[s[block[i][0]]]; 392 has -= 0; 393 } 394 if(flag[s[block[i][1]]]) { 395 ++cnt; 396 sum += col[s[block[i][1]]]; 397 has -= 1; 398 } 399 if(flag[s[block[i][2]]]){ 400 ++cnt; 401 sum+=col[s[block[i][2]]]; 402 has-=2; 403 } 404 if(cnt != 2) continue; 405 if(sum == 'B'+'W') col[s[block[i][has]]] = 'O'; 406 if(sum == 'B'+'Y') col[s[block[i][has]]] = 'G'; 407 if(sum == 'Y'+'W') col[s[block[i][has]]] = 'R'; 408 } 409 rep(i, 0, 24) s[i]=col[s[i]]; 410 } 411 412 int main() { 413 ios::sync_with_stdio(false); 414 #ifndef ONLINE_JUDGE 415 freopen("data.in", "r", stdin); 416 freopen("data.out", "w", stdout); 417 #endif 418 419 int t; 420 char ch; 421 int p[24]; 422 423 { 424 #define PUSHP(a, b, c, d) {p[l++]=a;p[l++]=b;p[l++]=c;p[l++]=d;} 425 int l = 0; 426 PUSHP(0, 1, 2, 3); 427 PUSHP(6, 7, 8, 9); 428 PUSHP(23, 22, 4, 5); 429 PUSHP(12, 13, 14, 15); 430 PUSHP(21, 20, 10, 11); 431 PUSHP(16, 17, 18, 19); 432 } 433 434 init(); 435 scanf("%d", &t); 436 rep(tt, 1, t+1) { 437 rep(i, 0, 24) { 438 while ((ch=getchar()) <= 32); 439 s[i] = ch; 440 } 441 transfer(); 442 rep(i, 0, 24) a[p[i]] = getVal(s[i]); 443 solve(); 444 } 445 446 #ifndef ONLINE_JUDGE 447 printf("time = %d.\n", (int)clock()); 448 #endif 449 450 return 0; 451 }
2.8 HDOJ 4397
三阶魔方,增加了X、Y、Z轴的旋转,一道模拟题。大写表示顺时针旋转,小写表示逆时针旋转,判定按照指定序列旋转后魔方能否复原。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 4397 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <bitset> 12 #include <algorithm> 13 #include <cstdio> 14 #include <cmath> 15 #include <ctime> 16 #include <cstring> 17 #include <climits> 18 #include <cctype> 19 #include <cassert> 20 #include <functional> 21 #include <iterator> 22 #include <iomanip> 23 using namespace std; 24 //#pragma comment(linker,"/STACK:102400000,1024000") 25 26 #define sti set<int> 27 #define stpii set<pair<int, int> > 28 #define mpii map<int,int> 29 #define vi vector<int> 30 #define pii pair<int,int> 31 #define vpii vector<pair<int,int> > 32 #define rep(i, a, n) for (int i=a;i<n;++i) 33 #define per(i, a, n) for (int i=n-1;i>=a;--i) 34 #define clr clear 35 #define pb push_back 36 #define mp make_pair 37 #define fir first 38 #define sec second 39 #define all(x) (x).begin(),(x).end() 40 #define SZ(x) ((int)(x).size()) 41 #define lson l, mid, rt<<1 42 #define rson mid+1, r, rt<<1|1 43 44 #define LEFT 0 45 #define FRONT 1 46 #define RIGHT 2 47 #define BACK 3 48 #define TOP 4 49 #define BOTTOM 5 50 int face[6][9] = { 51 /*Left*/ {9, 10, 11, 21, 22, 23, 33, 34, 35}, 52 /*Front*/ {12, 13, 14, 24, 25, 26, 36, 37, 38}, 53 /*Right*/ {15, 16, 17, 27, 28, 29, 39, 40, 41}, 54 /*Back*/ {18, 19, 20, 30, 31, 32, 42, 43, 44}, 55 /*Top*/ {0, 1, 2, 3, 4, 5, 6, 7, 8}, 56 /*Bottom*/ {45, 46, 47, 48, 49, 50, 51, 52, 53} 57 }; 58 59 char ops[215]; 60 char s[56], d[56]; 61 int q; 62 vector<vi> vpos; 63 64 vi counter(const vi& p) { 65 int a[56], b[56]; 66 67 rep(i, 0, 54) a[i] = i; 68 rep(i, 0, 3) { 69 rep(j, 0, 54) b[j] = a[p[j]]; 70 memcpy(a, b, sizeof(b)); 71 } 72 73 return vi(a, a+54); 74 } 75 76 void init() { 77 int a[56], b[56]; 78 79 #define MOVE_ROW(des, src)\ 80 {\ 81 rep(i, 0, 3)\ 82 b[face[des][i]] = a[face[src][i]];\ 83 } 84 85 #define MOVE_ROW_(des, src)\ 86 {\ 87 rep(i, 6, 9)\ 88 b[face[des][i]] = a[face[src][i]];\ 89 } 90 91 #define MOVE_COL(des, src)\ 92 {\ 93 rep(i, 0, 3)\ 94 b[face[des][i*3]] = a[face[src][i*3]];\ 95 } 96 #define FORCE_MOVE(da, sa, db, sb, dc, sc)\ 97 {\ 98 b[da] = a[sa];\ 99 b[db] = a[sb];\ 100 b[dc] = a[sc];\ 101 } 102 103 104 // rotate U 105 { 106 107 rep(i, 0, 54) a[i] = i; 108 109 memcpy(b, a, sizeof(a)); 110 int* mf = face[TOP]; 111 rep(i, 0, 3) { 112 rep(j, 0, 3) { 113 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 114 } 115 } 116 MOVE_ROW(LEFT, FRONT); 117 MOVE_ROW(FRONT, RIGHT); 118 MOVE_ROW(RIGHT, BACK); 119 MOVE_ROW(BACK, LEFT); 120 121 vi vtmp(b, b+54); 122 vpos.pb(vtmp); 123 vpos.pb(counter(vtmp)); 124 } 125 126 // rotate R 127 { 128 rep(i, 0, 54) a[i] = i; 129 130 memcpy(b, a, sizeof(a)); 131 int* mf = face[RIGHT]; 132 rep(i, 0, 3) { 133 rep(j, 0, 3) { 134 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 135 } 136 } 137 FORCE_MOVE(face[TOP][2], face[FRONT][2], face[TOP][5], face[FRONT][5], face[TOP][8], face[FRONT][8]); // MOVE_COL(TOP, FRONT); 138 FORCE_MOVE(face[FRONT][2], face[BOTTOM][2], face[FRONT][5], face[BOTTOM][5], face[FRONT][8], face[BOTTOM][8]); // MOVE_COL(FRONT, BOTTOM); 139 FORCE_MOVE(face[BOTTOM][2], 42, face[BOTTOM][5], 30, face[BOTTOM][8], 18); // MOVE_COL(BOTTOM, BACK); 140 FORCE_MOVE(42, 2, 30, 5, 18, 8); // MOVE_COL(BACK, TOP); 141 142 vi vtmp(b, b+54); 143 vpos.pb(vtmp); 144 vpos.pb(counter(vtmp)); 145 } 146 147 // rotate F 148 { 149 rep(i, 0, 54) a[i] = i; 150 151 memcpy(b, a, sizeof(a)); 152 int* mf = face[FRONT]; 153 rep(i, 0, 3) { 154 rep(j, 0, 3) { 155 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 156 } 157 } 158 FORCE_MOVE(face[TOP][6], face[LEFT][8], face[TOP][7], face[LEFT][5], face[TOP][8], face[LEFT][2]); // MOVE_COL(TOP, LEFT); 159 FORCE_MOVE(face[RIGHT][0], face[TOP][6], face[RIGHT][3], face[TOP][7], face[RIGHT][6], face[TOP][8]); // MOVE_COL(RIGHT, TOP); 160 FORCE_MOVE(face[BOTTOM][0], face[RIGHT][6], face[BOTTOM][1], face[RIGHT][3], face[BOTTOM][2], face[RIGHT][0]); // MOVE_COL(BOTTOM, RIGHT); 161 FORCE_MOVE(face[LEFT][2], face[BOTTOM][0], face[LEFT][5], face[BOTTOM][1], face[LEFT][8], face[BOTTOM][2]); // MOVE_COL(LEFT, BOTTOM); 162 163 vi vtmp(b, b+54); 164 vpos.pb(vtmp); 165 vpos.pb(counter(vtmp)); 166 } 167 168 // rotate D 169 { 170 rep(i, 0, 54) a[i] = i; 171 172 memcpy(b, a, sizeof(a)); 173 int* mf = face[BOTTOM]; 174 rep(i, 0, 3) { 175 rep(j, 0, 3) { 176 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 177 } 178 } 179 MOVE_ROW_(FRONT, LEFT); 180 MOVE_ROW_(RIGHT, FRONT); 181 MOVE_ROW_(BACK, RIGHT); 182 MOVE_ROW_(LEFT, BACK); 183 184 vi vtmp(b, b+54); 185 vpos.pb(vtmp); 186 vpos.pb(counter(vtmp)); 187 } 188 189 // rotate L 190 { 191 rep(i, 0, 54) a[i] = i; 192 193 memcpy(b, a, sizeof(a)); 194 int* mf = face[LEFT]; 195 rep(i, 0, 3) { 196 rep(j, 0, 3) { 197 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 198 } 199 } 200 MOVE_COL(FRONT, TOP); 201 MOVE_COL(BOTTOM, FRONT); 202 FORCE_MOVE(20, 51, 32, 48, 44, 45); //MOVE_COL(BACK, BOTTOM); 203 FORCE_MOVE(0, 44, 3, 32, 6, 20); // MOVE_COL(TOP, BACK); 204 205 vi vtmp(b, b+54); 206 vpos.pb(vtmp); 207 vpos.pb(counter(vtmp)); 208 } 209 210 // rotate B 211 { 212 rep(i, 0, 54) a[i] = i; 213 214 memcpy(b, a, sizeof(a)); 215 int* mf = face[BACK]; 216 rep(i, 0, 3) { 217 rep(j, 0, 3) { 218 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 219 } 220 } 221 FORCE_MOVE(face[LEFT][0], face[TOP][2], face[LEFT][3], face[TOP][1], face[LEFT][6], face[TOP][0]); // MOVE(LEFT, TOP); 222 FORCE_MOVE(face[TOP][0], face[RIGHT][2], face[TOP][1], face[RIGHT][5], face[TOP][2], face[RIGHT][8]); // MOVE(TOP, RIGHT); 223 FORCE_MOVE(face[RIGHT][2], 53, face[RIGHT][5], 52, face[RIGHT][8], 51); // MOVE(RIGHT, BOTTOM); 224 FORCE_MOVE(53, face[LEFT][6], 52, face[LEFT][3], 51, face[LEFT][0]); // MOVE(BOTTOM, LEFT); 225 226 vi vtmp(b, b+54); 227 vpos.pb(vtmp); 228 vpos.pb(counter(vtmp)); 229 } 230 231 // rotate X 232 { 233 234 rep(i, 0, 54) a[i] = i; 235 236 memcpy(b, a, sizeof(a)); 237 FORCE_MOVE(face[LEFT][3], face[FRONT][3], face[LEFT][4], face[FRONT][4], face[LEFT][5], face[FRONT][5]); 238 FORCE_MOVE(face[FRONT][3], face[RIGHT][3], face[FRONT][4], face[RIGHT][4], face[FRONT][5], face[RIGHT][5]); 239 FORCE_MOVE(face[RIGHT][3], face[BACK][3], face[RIGHT][4], face[BACK][4], face[RIGHT][5], face[BACK][5]); 240 FORCE_MOVE(face[BACK][3],face[LEFT][3],face[BACK][4],face[LEFT][4],face[BACK][5],face[LEFT][5]); 241 242 vi vtmp(b, b+54); 243 vpos.pb(vtmp); 244 vpos.pb(counter(vtmp)); 245 } 246 247 // rotateY 248 { 249 250 rep(i, 0, 54) a[i] = i; 251 252 memcpy(b, a, sizeof(a)); 253 FORCE_MOVE(face[TOP][1], face[FRONT][1], face[TOP][4], face[FRONT][4], face[TOP][7], face[FRONT][7]); 254 FORCE_MOVE(face[BACK][7], face[TOP][1], face[BACK][4], face[TOP][4], face[BACK][1], face[TOP][7]); 255 FORCE_MOVE(face[BOTTOM][7], face[BACK][1], face[BOTTOM][4], face[BACK][4], face[BOTTOM][1], face[BACK][7]); 256 FORCE_MOVE(face[FRONT][1],face[BOTTOM][1],face[FRONT][4],face[BOTTOM][4],face[FRONT][7],face[BOTTOM][7]); 257 258 vi vtmp(b, b+54); 259 vpos.pb(vtmp); 260 vpos.pb(counter(vtmp)); 261 } 262 263 // rotateZ 264 { 265 266 rep(i, 0, 54) a[i] = i; 267 268 memcpy(b, a, sizeof(a)); 269 FORCE_MOVE(face[TOP][3], face[LEFT][7], face[TOP][4], face[LEFT][4], face[TOP][5], face[LEFT][1]); 270 FORCE_MOVE(face[RIGHT][1], face[TOP][3], face[RIGHT][4], face[TOP][4], face[RIGHT][7], face[TOP][5]); 271 FORCE_MOVE(face[BOTTOM][5], face[RIGHT][1], face[BOTTOM][4], face[RIGHT][4], face[BOTTOM][3], face[RIGHT][7]); 272 FORCE_MOVE(face[LEFT][1],face[BOTTOM][3],face[LEFT][4],face[BOTTOM][4],face[LEFT][7],face[BOTTOM][5]); 273 274 vi vtmp(b, b+54); 275 vpos.pb(vtmp); 276 vpos.pb(counter(vtmp)); 277 } 278 } 279 280 void rotate(char ch) { 281 static char uc[] = "URFDLBXYZ"; 282 static char lc[] = "urfdlbxyz"; 283 284 int idx; 285 286 if (islower(ch)) { 287 idx = strchr(lc, ch) - lc; 288 idx = (idx << 1) + 1; 289 290 } else { 291 idx = strchr(uc, ch) - uc; 292 idx = (idx << 1); 293 } 294 295 #ifndef ONLINE_JUDGE 296 assert(idx>=0 && idx<SZ(vpos)); 297 #endif 298 299 memcpy(d, s, sizeof(d)); 300 rep(j, 0, 54) 301 s[j] = d[vpos[idx][j]]; 302 } 303 304 void printAns(char *s) { 305 int idx = 0; 306 307 rep(i, 0, 3) { 308 printf(" "); 309 rep(j, 0, 3) { 310 putchar(' '); 311 putchar(s[idx++]); 312 } 313 putchar('\n'); 314 } 315 316 rep(i, 0, 3) { 317 rep(j, 0, 12) { 318 if (j) putchar(' '); 319 putchar(s[idx++]); 320 } 321 putchar('\n'); 322 } 323 324 rep(i, 0, 3) { 325 printf(" "); 326 rep(j, 0, 3) { 327 putchar(' '); 328 putchar(s[idx++]); 329 } 330 putchar('\n'); 331 } 332 } 333 334 void solve() { 335 int len = strlen(ops); 336 337 rep(i, 0, 54) s[i] = i; 338 339 rep(i, 0, len) { 340 rotate(ops[i]); 341 } 342 343 bool flag = true; 344 rep(i, 0, 54) { 345 if (s[i] != i) { 346 flag = false; 347 break; 348 } 349 } 350 351 puts(flag ? "Yes":"No"); 352 } 353 354 int main() { 355 cin.tie(0); 356 ios::sync_with_stdio(false); 357 #ifndef ONLINE_JUDGE 358 freopen("data.in", "r", stdin); 359 freopen("data.out", "w", stdout); 360 #endif 361 362 int t = 0; 363 364 init(); 365 while (scanf("%s", ops)!=EOF) { 366 if (t) 367 putchar('\n'); 368 solve(); 369 ++t; 370 } 371 372 #ifndef ONLINE_JUDGE 373 printf("time = %ldms.\n", clock()); 374 #endif 375 376 return 0; 377 }
2.9 POJ 1297
三阶魔方模拟,利用前面的代码稍微改改可以直接过了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 1290 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <bitset> 12 #include <algorithm> 13 #include <cstdio> 14 #include <cmath> 15 #include <ctime> 16 #include <cstring> 17 #include <climits> 18 #include <cctype> 19 #include <cassert> 20 #include <functional> 21 #include <iterator> 22 #include <iomanip> 23 using namespace std; 24 //#pragma comment(linker,"/STACK:102400000,1024000") 25 26 #define sti set<int> 27 #define stpii set<pair<int, int> > 28 #define mpii map<int,int> 29 #define vi vector<int> 30 #define pii pair<int,int> 31 #define vpii vector<pair<int,int> > 32 #define rep(i, a, n) for (int i=a;i<n;++i) 33 #define per(i, a, n) for (int i=n-1;i>=a;--i) 34 #define clr clear 35 #define pb push_back 36 #define mp make_pair 37 #define fir first 38 #define sec second 39 #define all(x) (x).begin(),(x).end() 40 #define SZ(x) ((int)(x).size()) 41 #define lson l, mid, rt<<1 42 #define rson mid+1, r, rt<<1|1 43 44 #define LEFT 0 45 #define FRONT 1 46 #define RIGHT 2 47 #define BACK 3 48 #define TOP 4 49 #define BOTTOM 5 50 int face[6][9] = { 51 /*Left*/ {9, 10, 11, 21, 22, 23, 33, 34, 35}, 52 /*Front*/ {12, 13, 14, 24, 25, 26, 36, 37, 38}, 53 /*Right*/ {15, 16, 17, 27, 28, 29, 39, 40, 41}, 54 /*Back*/ {18, 19, 20, 30, 31, 32, 42, 43, 44}, 55 /*Top*/ {0, 1, 2, 3, 4, 5, 6, 7, 8}, 56 /*Bottom*/ {45, 46, 47, 48, 49, 50, 51, 52, 53} 57 }; 58 59 char s[56], d[56]; 60 int q; 61 vector<vi> vpos; 62 63 vi counter(const vi& p) { 64 int a[56], b[56]; 65 66 rep(i, 0, 54) a[i] = i; 67 rep(i, 0, 3) { 68 rep(j, 0, 54) b[j] = a[p[j]]; 69 memcpy(a, b, sizeof(b)); 70 } 71 72 return vi(a, a+54); 73 } 74 75 void init() { 76 int a[56], b[56]; 77 78 #define MOVE_ROW(des, src)\ 79 {\ 80 rep(i, 0, 3)\ 81 b[face[des][i]] = a[face[src][i]];\ 82 } 83 84 #define MOVE_ROW_(des, src)\ 85 {\ 86 rep(i, 6, 9)\ 87 b[face[des][i]] = a[face[src][i]];\ 88 } 89 90 #define MOVE_COL(des, src)\ 91 {\ 92 rep(i, 0, 3)\ 93 b[face[des][i*3]] = a[face[src][i*3]];\ 94 } 95 #define FORCE_MOVE(da, sa, db, sb, dc, sc)\ 96 {\ 97 b[da] = a[sa];\ 98 b[db] = a[sb];\ 99 b[dc] = a[sc];\ 100 } 101 102 103 // rotate LEFT 104 { 105 rep(i, 0, 54) a[i] = i; 106 107 memcpy(b, a, sizeof(a)); 108 int* mf = face[LEFT]; 109 rep(i, 0, 3) { 110 rep(j, 0, 3) { 111 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 112 } 113 } 114 MOVE_COL(FRONT, TOP); 115 MOVE_COL(BOTTOM, FRONT); 116 FORCE_MOVE(20, 51, 32, 48, 44, 45); //MOVE_COL(BACK, BOTTOM); 117 FORCE_MOVE(0, 44, 3, 32, 6, 20); // MOVE_COL(TOP, BACK); 118 119 vi vtmp(b, b+54); 120 vpos.pb(vtmp); 121 vpos.pb(counter(vtmp)); 122 } 123 124 // rotate FRONT 125 { 126 rep(i, 0, 54) a[i] = i; 127 128 memcpy(b, a, sizeof(a)); 129 int* mf = face[FRONT]; 130 rep(i, 0, 3) { 131 rep(j, 0, 3) { 132 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 133 } 134 } 135 FORCE_MOVE(face[TOP][6], face[LEFT][8], face[TOP][7], face[LEFT][5], face[TOP][8], face[LEFT][2]); // MOVE_COL(TOP, LEFT); 136 FORCE_MOVE(face[RIGHT][0], face[TOP][6], face[RIGHT][3], face[TOP][7], face[RIGHT][6], face[TOP][8]); // MOVE_COL(RIGHT, TOP); 137 FORCE_MOVE(face[BOTTOM][0], face[RIGHT][6], face[BOTTOM][1], face[RIGHT][3], face[BOTTOM][2], face[RIGHT][0]); // MOVE_COL(BOTTOM, RIGHT); 138 FORCE_MOVE(face[LEFT][2], face[BOTTOM][0], face[LEFT][5], face[BOTTOM][1], face[LEFT][8], face[BOTTOM][2]); // MOVE_COL(LEFT, BOTTOM); 139 140 vi vtmp(b, b+54); 141 vpos.pb(vtmp); 142 vpos.pb(counter(vtmp)); 143 } 144 145 // rotate RIGHT 146 { 147 rep(i, 0, 54) a[i] = i; 148 149 memcpy(b, a, sizeof(a)); 150 int* mf = face[RIGHT]; 151 rep(i, 0, 3) { 152 rep(j, 0, 3) { 153 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 154 } 155 } 156 FORCE_MOVE(face[TOP][2], face[FRONT][2], face[TOP][5], face[FRONT][5], face[TOP][8], face[FRONT][8]); // MOVE_COL(TOP, FRONT); 157 FORCE_MOVE(face[FRONT][2], face[BOTTOM][2], face[FRONT][5], face[BOTTOM][5], face[FRONT][8], face[BOTTOM][8]); // MOVE_COL(FRONT, BOTTOM); 158 FORCE_MOVE(face[BOTTOM][2], 42, face[BOTTOM][5], 30, face[BOTTOM][8], 18); // MOVE_COL(BOTTOM, BACK); 159 FORCE_MOVE(42, 2, 30, 5, 18, 8); // MOVE_COL(BACK, TOP); 160 161 vi vtmp(b, b+54); 162 vpos.pb(vtmp); 163 vpos.pb(counter(vtmp)); 164 } 165 166 // rotate BACK 167 { 168 rep(i, 0, 54) a[i] = i; 169 170 memcpy(b, a, sizeof(a)); 171 int* mf = face[BACK]; 172 rep(i, 0, 3) { 173 rep(j, 0, 3) { 174 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 175 } 176 } 177 FORCE_MOVE(face[LEFT][0], face[TOP][2], face[LEFT][3], face[TOP][1], face[LEFT][6], face[TOP][0]); // MOVE(LEFT, TOP); 178 FORCE_MOVE(face[TOP][0], face[RIGHT][2], face[TOP][1], face[RIGHT][5], face[TOP][2], face[RIGHT][8]); // MOVE(TOP, RIGHT); 179 FORCE_MOVE(face[RIGHT][2], 53, face[RIGHT][5], 52, face[RIGHT][8], 51); // MOVE(RIGHT, BOTTOM); 180 FORCE_MOVE(53, face[LEFT][6], 52, face[LEFT][3], 51, face[LEFT][0]); // MOVE(BOTTOM, LEFT); 181 182 vi vtmp(b, b+54); 183 vpos.pb(vtmp); 184 vpos.pb(counter(vtmp)); 185 } 186 187 // rotate Top 188 { 189 190 rep(i, 0, 54) a[i] = i; 191 192 memcpy(b, a, sizeof(a)); 193 int* mf = face[TOP]; 194 rep(i, 0, 3) { 195 rep(j, 0, 3) { 196 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 197 } 198 } 199 MOVE_ROW(LEFT, FRONT); 200 MOVE_ROW(FRONT, RIGHT); 201 MOVE_ROW(RIGHT, BACK); 202 MOVE_ROW(BACK, LEFT); 203 204 vi vtmp(b, b+54); 205 vpos.pb(vtmp); 206 vpos.pb(counter(vtmp)); 207 } 208 209 // rotate BOTTOM 210 { 211 rep(i, 0, 54) a[i] = i; 212 213 memcpy(b, a, sizeof(a)); 214 int* mf = face[BOTTOM]; 215 rep(i, 0, 3) { 216 rep(j, 0, 3) { 217 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 218 } 219 } 220 MOVE_ROW_(FRONT, LEFT); 221 MOVE_ROW_(RIGHT, FRONT); 222 MOVE_ROW_(BACK, RIGHT); 223 MOVE_ROW_(LEFT, BACK); 224 225 vi vtmp(b, b+54); 226 vpos.pb(vtmp); 227 vpos.pb(counter(vtmp)); 228 } 229 } 230 231 void rotate(int x) { 232 int v = abs(x) - 1; 233 int idx = v * 2; 234 if (x < 0) idx += 1; 235 memcpy(d, s, sizeof(d)); 236 vi& p = vpos[idx]; 237 #ifndef ONLINE_JUDGE 238 assert(idx>=0 && idx<SZ(p)); 239 #endif 240 rep(i, 0, 54) s[i] = d[p[i]]; 241 } 242 243 bool judge() { 244 rep(i, 0, 6) { 245 rep(j, 1, 9) { 246 if (s[face[i][j]] != s[face[i][0]]) 247 return false; 248 } 249 } 250 return true; 251 } 252 253 void solve() { 254 int x; 255 256 while (scanf("%d", &x)!=EOF && x) { 257 rotate(x); 258 } 259 260 bool flag = judge(); 261 puts(flag ? "Yes, grandpa!" : "No, you are wrong!"); 262 } 263 264 int main() { 265 cin.tie(0); 266 ios::sync_with_stdio(false); 267 #ifndef ONLINE_JUDGE 268 freopen("data.in", "r", stdin); 269 freopen("data.out", "w", stdout); 270 #endif 271 272 int t; 273 char op[4]; 274 275 init(); 276 scanf("%d", &t); 277 rep(tt, 1, t+1) { 278 rep(i, 0, 54) { 279 scanf("%s", op); 280 s[i] = op[0]; 281 } 282 solve(); 283 } 284 285 #ifndef ONLINE_JUDGE 286 printf("time = %ldms.\n", clock()); 287 #endif 288 289 return 0; 290 }
2.10 POJ 3701
三阶魔方搜索,算法还是双广。但是这题wa了好几次,一定要注意读题,首先面1表示FRONT,同样旋转方式都是基于此前提下的,展开方式也是。因此,需要重新映射一下。这个题目不要使用状态等价,可以直接用longlong表示状态,因为$2^{54}$足够了,这里的1的个数一定为9。代码使用G++可以790ms过,C++一直超时。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 3701 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <bitset> 12 #include <algorithm> 13 #include <cstdio> 14 #include <cmath> 15 #include <ctime> 16 #include <cstring> 17 #include <climits> 18 #include <cctype> 19 #include <cassert> 20 #include <functional> 21 #include <iterator> 22 #include <iomanip> 23 using namespace std; 24 //#pragma comment(linker,"/STACK:102400000,1024000") 25 26 #define sti set<int> 27 #define stpii set<pair<int, int> > 28 #define mpii map<int,int> 29 #define vi vector<int> 30 #define pii pair<int,int> 31 #define vpii vector<pair<int,int> > 32 #define rep(i, a, n) for (int i=a;i<n;++i) 33 #define per(i, a, n) for (int i=n-1;i>=a;--i) 34 #define clr clear 35 #define pb push_back 36 #define mp make_pair 37 #define fir first 38 #define sec second 39 #define all(x) (x).begin(),(x).end() 40 #define SZ(x) ((int)(x).size()) 41 #define lson l, mid, rt<<1 42 #define rson mid+1, r, rt<<1|1 43 44 typedef long long LL; 45 #define LEFT 0 46 #define FRONT 1 47 #define RIGHT 2 48 #define BACK 3 49 #define TOP 4 50 #define BOTTOM 5 51 int face[6][9] = { 52 /*Left*/ {9, 10, 11, 21, 22, 23, 33, 34, 35}, 53 /*Front*/ {12, 13, 14, 24, 25, 26, 36, 37, 38}, 54 /*Right*/ {15, 16, 17, 27, 28, 29, 39, 40, 41}, 55 /*Back*/ {18, 19, 20, 30, 31, 32, 42, 43, 44}, 56 /*Top*/ {0, 1, 2, 3, 4, 5, 6, 7, 8}, 57 /*Bottom*/ {45, 46, 47, 48, 49, 50, 51, 52, 53} 58 }; 59 60 char s[56], d[56]; 61 int one; 62 vector<vi> movp; 63 vector<vi> vpos; 64 map<LL, pair<LL,int> > tb[2]; 65 66 vi counter(const vi& p) { 67 int a[56], b[56]; 68 69 rep(i, 0, 54) a[i] = i; 70 rep(i, 0, 3) { 71 rep(j, 0, 54) b[j] = a[p[j]]; 72 memcpy(a, b, sizeof(b)); 73 } 74 75 return vi(a, a+54); 76 } 77 78 void init_pos(); 79 void init_bfs(); 80 void init() { 81 int a[56], b[56]; 82 83 #define MOVE_ROW(des, src)\ 84 {\ 85 rep(i, 0, 3)\ 86 b[face[des][i]] = a[face[src][i]];\ 87 } 88 89 #define MOVE_ROW_(des, src)\ 90 {\ 91 rep(i, 6, 9)\ 92 b[face[des][i]] = a[face[src][i]];\ 93 } 94 95 #define MOVE_COL(des, src)\ 96 {\ 97 rep(i, 0, 3)\ 98 b[face[des][i*3]] = a[face[src][i*3]];\ 99 } 100 #define FORCE_MOVE(da, sa, db, sb, dc, sc)\ 101 {\ 102 b[da] = a[sa];\ 103 b[db] = a[sb];\ 104 b[dc] = a[sc];\ 105 } 106 107 // rotate U 108 { 109 110 rep(i, 0, 54) a[i] = i; 111 112 memcpy(b, a, sizeof(a)); 113 int* mf = face[TOP]; 114 rep(i, 0, 3) { 115 rep(j, 0, 3) { 116 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 117 } 118 } 119 MOVE_ROW(LEFT, FRONT); 120 MOVE_ROW(FRONT, RIGHT); 121 MOVE_ROW(RIGHT, BACK); 122 MOVE_ROW(BACK, LEFT); 123 124 vi vtmp(b, b+54); 125 movp.pb(vtmp); 126 movp.pb(counter(vtmp)); 127 } 128 129 // rotate X 130 { 131 132 rep(i, 0, 54) a[i] = i; 133 134 memcpy(b, a, sizeof(a)); 135 FORCE_MOVE(face[LEFT][3], face[FRONT][3], face[LEFT][4], face[FRONT][4], face[LEFT][5], face[FRONT][5]); 136 FORCE_MOVE(face[FRONT][3], face[RIGHT][3], face[FRONT][4], face[RIGHT][4], face[FRONT][5], face[RIGHT][5]); 137 FORCE_MOVE(face[RIGHT][3], face[BACK][3], face[RIGHT][4], face[BACK][4], face[RIGHT][5], face[BACK][5]); 138 FORCE_MOVE(face[BACK][3],face[LEFT][3],face[BACK][4],face[LEFT][4],face[BACK][5],face[LEFT][5]); 139 140 vi vtmp(b, b+54); 141 movp.pb(vtmp); 142 movp.pb(counter(vtmp)); 143 } 144 145 // rotate D 146 { 147 rep(i, 0, 54) a[i] = i; 148 149 memcpy(b, a, sizeof(a)); 150 int* mf = face[BOTTOM]; 151 rep(i, 0, 3) { 152 rep(j, 0, 3) { 153 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 154 } 155 } 156 MOVE_ROW_(FRONT, LEFT); 157 MOVE_ROW_(RIGHT, FRONT); 158 MOVE_ROW_(BACK, RIGHT); 159 MOVE_ROW_(LEFT, BACK); 160 161 vi vtmp(b, b+54); 162 movp.pb(counter(vtmp)); 163 movp.pb(vtmp); 164 } 165 166 // rotate L 167 { 168 rep(i, 0, 54) a[i] = i; 169 170 memcpy(b, a, sizeof(a)); 171 int* mf = face[LEFT]; 172 rep(i, 0, 3) { 173 rep(j, 0, 3) { 174 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 175 } 176 } 177 MOVE_COL(FRONT, TOP); 178 MOVE_COL(BOTTOM, FRONT); 179 FORCE_MOVE(20, 51, 32, 48, 44, 45); //MOVE_COL(BACK, BOTTOM); 180 FORCE_MOVE(0, 44, 3, 32, 6, 20); // MOVE_COL(TOP, BACK); 181 182 vi vtmp(b, b+54); 183 movp.pb(counter(vtmp)); 184 movp.pb(vtmp); 185 } 186 187 // rotateY 188 { 189 190 rep(i, 0, 54) a[i] = i; 191 192 memcpy(b, a, sizeof(a)); 193 FORCE_MOVE(face[TOP][1], face[FRONT][1], face[TOP][4], face[FRONT][4], face[TOP][7], face[FRONT][7]); 194 FORCE_MOVE(face[BACK][7], face[TOP][1], face[BACK][4], face[TOP][4], face[BACK][1], face[TOP][7]); 195 FORCE_MOVE(face[BOTTOM][7], face[BACK][1], face[BOTTOM][4], face[BACK][4], face[BOTTOM][1], face[BACK][7]); 196 FORCE_MOVE(face[FRONT][1],face[BOTTOM][1],face[FRONT][4],face[BOTTOM][4],face[FRONT][7],face[BOTTOM][7]); 197 198 vi vtmp(b, b+54); 199 movp.pb(vtmp); 200 movp.pb(counter(vtmp)); 201 } 202 203 // rotate R 204 { 205 rep(i, 0, 54) a[i] = i; 206 207 memcpy(b, a, sizeof(a)); 208 int* mf = face[RIGHT]; 209 rep(i, 0, 3) { 210 rep(j, 0, 3) { 211 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 212 } 213 } 214 FORCE_MOVE(face[TOP][2], face[FRONT][2], face[TOP][5], face[FRONT][5], face[TOP][8], face[FRONT][8]); // MOVE_COL(TOP, FRONT); 215 FORCE_MOVE(face[FRONT][2], face[BOTTOM][2], face[FRONT][5], face[BOTTOM][5], face[FRONT][8], face[BOTTOM][8]); // MOVE_COL(FRONT, BOTTOM); 216 FORCE_MOVE(face[BOTTOM][2], 42, face[BOTTOM][5], 30, face[BOTTOM][8], 18); // MOVE_COL(BOTTOM, BACK); 217 FORCE_MOVE(42, 2, 30, 5, 18, 8); // MOVE_COL(BACK, TOP); 218 219 vi vtmp(b, b+54); 220 movp.pb(vtmp); 221 movp.pb(counter(vtmp)); 222 } 223 224 // rotate B 225 { 226 rep(i, 0, 54) a[i] = i; 227 228 memcpy(b, a, sizeof(a)); 229 int* mf = face[BACK]; 230 rep(i, 0, 3) { 231 rep(j, 0, 3) { 232 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 233 } 234 } 235 FORCE_MOVE(face[LEFT][0], face[TOP][2], face[LEFT][3], face[TOP][1], face[LEFT][6], face[TOP][0]); // MOVE(LEFT, TOP); 236 FORCE_MOVE(face[TOP][0], face[RIGHT][2], face[TOP][1], face[RIGHT][5], face[TOP][2], face[RIGHT][8]); // MOVE(TOP, RIGHT); 237 FORCE_MOVE(face[RIGHT][2], 53, face[RIGHT][5], 52, face[RIGHT][8], 51); // MOVE(RIGHT, BOTTOM); 238 FORCE_MOVE(53, face[LEFT][6], 52, face[LEFT][3], 51, face[LEFT][0]); // MOVE(BOTTOM, LEFT); 239 240 vi vtmp(b, b+54); 241 movp.pb(vtmp); 242 movp.pb(counter(vtmp)); 243 } 244 245 // rotateZ 246 { 247 248 rep(i, 0, 54) a[i] = i; 249 250 memcpy(b, a, sizeof(a)); 251 FORCE_MOVE(face[TOP][3], face[LEFT][7], face[TOP][4], face[LEFT][4], face[TOP][5], face[LEFT][1]); 252 FORCE_MOVE(face[RIGHT][1], face[TOP][3], face[RIGHT][4], face[TOP][4], face[RIGHT][7], face[TOP][5]); 253 FORCE_MOVE(face[BOTTOM][5], face[RIGHT][1], face[BOTTOM][4], face[RIGHT][4], face[BOTTOM][3], face[RIGHT][7]); 254 FORCE_MOVE(face[LEFT][1],face[BOTTOM][3],face[LEFT][4],face[BOTTOM][4],face[LEFT][7],face[BOTTOM][5]); 255 256 vi vtmp(b, b+54); 257 movp.pb(counter(vtmp)); 258 movp.pb(vtmp); 259 } 260 261 // rotate F 262 { 263 rep(i, 0, 54) a[i] = i; 264 265 memcpy(b, a, sizeof(a)); 266 int* mf = face[FRONT]; 267 rep(i, 0, 3) { 268 rep(j, 0, 3) { 269 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 270 } 271 } 272 FORCE_MOVE(face[TOP][6], face[LEFT][8], face[TOP][7], face[LEFT][5], face[TOP][8], face[LEFT][2]); // MOVE_COL(TOP, LEFT); 273 FORCE_MOVE(face[RIGHT][0], face[TOP][6], face[RIGHT][3], face[TOP][7], face[RIGHT][6], face[TOP][8]); // MOVE_COL(RIGHT, TOP); 274 FORCE_MOVE(face[BOTTOM][0], face[RIGHT][6], face[BOTTOM][1], face[RIGHT][3], face[BOTTOM][2], face[RIGHT][0]); // MOVE_COL(BOTTOM, RIGHT); 275 FORCE_MOVE(face[LEFT][2], face[BOTTOM][0], face[LEFT][5], face[BOTTOM][1], face[LEFT][8], face[BOTTOM][2]); // MOVE_COL(LEFT, BOTTOM); 276 277 vi vtmp(b, b+54); 278 movp.pb(counter(vtmp)); 279 movp.pb(vtmp); 280 } 281 } 282 283 bool judge(char *s) { 284 int c = 0; 285 rep(j, 0, 9) 286 c += s[face[FRONT][j]] - '0'; 287 288 return c == one; 289 } 290 291 inline LL zip(char *s) { 292 LL ret = 0; 293 294 rep(i, 0, 54) { 295 if (s[i] == '1') 296 ret |= 1LL << i; 297 } 298 299 return ret; 300 } 301 302 inline void unzip(char *s, LL val) { 303 rep(i, 0, 54) { 304 if (val & (1LL<<i)) 305 s[i] = '1'; 306 else 307 s[i] = '0'; 308 } 309 } 310 311 struct node_t { 312 LL st; 313 int pre; 314 int dep; 315 316 node_t() {} 317 node_t(LL st, int pre, int dep): 318 st(st), pre(pre), dep(dep) {} 319 320 void print() { 321 char sa[55]; 322 unzip(sa, st); 323 324 int idx = 0; 325 326 printf("op = %d:\n", pre+1); 327 rep(i, 0, 3) { 328 printf(" "); 329 rep(j, 0, 3) putchar(sa[idx++]); 330 putchar('\n'); 331 } 332 333 rep(i, 0, 3) { 334 rep(j, 0, 12) putchar(sa[idx++]); 335 putchar('\n'); 336 } 337 338 rep(i, 0, 3) { 339 printf(" "); 340 rep(j, 0, 3) putchar(sa[idx++]); 341 putchar('\n'); 342 } 343 putchar('\n'); 344 } 345 }; 346 347 inline bool Visit(LL st, int idx) { 348 return tb[idx].count(st) > 0; 349 } 350 351 queue<node_t> Q[2]; 352 353 LL bfs(int idx) { 354 queue<node_t>& Q = ::Q[idx]; 355 map<LL, pair<LL,int> >& tb = ::tb[idx]; 356 const int sz = SZ(movp); 357 int szQ = SZ(Q); 358 node_t nd, d; 359 static char sa[54], sb[54]; 360 361 while (szQ--) { 362 nd = Q.front(); 363 Q.pop(); 364 unzip(sa, nd.st); 365 rep(i, 0, sz) { 366 if ((i^1) == nd.pre) continue; 367 if (i==nd.pre && nd.dep>=2) continue; 368 369 rep(j, 0, 54) sb[j] = sa[movp[i][j]]; 370 d.st = zip(sb); 371 if (i != nd.pre) { 372 d.dep = 1; 373 d.pre = i; 374 } else { 375 d.dep++; 376 } 377 378 if (Visit(d.st, idx)) continue; 379 tb[d.st] = mp(nd.st, i); 380 if (Visit(d.st, idx^1)) return d.st; 381 382 Q.push(d); 383 } 384 break; 385 } 386 387 return -1; 388 } 389 390 void solve() { 391 int& c = one; 392 393 c = 0; 394 rep(i, 0, 54) { 395 c += s[i] - '0'; 396 } 397 398 if (judge(s)) { 399 puts("yes"); 400 puts("1"); 401 puts("13"); 402 return ; 403 } 404 405 LL bst = zip(s); 406 Q[0].push(node_t(bst, -1, -1)); 407 tb[0][bst] = mp(-1, -1); 408 409 memset(s, '0', sizeof(s)); 410 rep(j, 0, 9) s[face[FRONT][j]] = '1'; 411 LL est = zip(s); 412 Q[1].push(node_t(est, -1, -1)); 413 tb[1][est] = mp(-1, -1); 414 415 LL st = -1; 416 int t = 5000; 417 while (!Q[0].empty() || !Q[1].empty()) { 418 if (t-- == 0) break; 419 if (!Q[0].empty()) { 420 st = bfs(0); 421 if (st >= 0) break; 422 } 423 if (!Q[1].empty()) { 424 st = bfs(1); 425 if (st >= 0) break; 426 } 427 } 428 429 if (st == -1) { 430 puts("no"); 431 return ; 432 } 433 434 LL st1 = st; 435 LL st2 = st; 436 vi ans1, ans2; 437 438 pair<LL,int> p; 439 while (st1 != -1) { 440 p = tb[0][st1]; 441 if (p.fir == -1) break; 442 ans1.pb(p.sec); 443 st1 = p.fir; 444 } 445 while (st2 != -1) { 446 p = tb[1][st2]; 447 if (p.fir == -1) break; 448 ans2.pb(p.sec); 449 st2 = p.fir; 450 } 451 452 printf("yes\n%d\n", SZ(ans1)+SZ(ans2)); 453 per(i, 0, SZ(ans1)) { 454 printf("%d\n", ans1[i]+1); 455 } 456 rep(i, 0, SZ(ans2)) { 457 printf("%d\n", (ans2[i]^1)+1); 458 } 459 460 // rep(i, 0, 2) { 461 // tb[i].clr(); 462 // while (!Q[i].empty()) Q[i].pop(); 463 // } 464 } 465 466 int main() { 467 cin.tie(0); 468 ios::sync_with_stdio(false); 469 #ifndef ONLINE_JUDGE 470 freopen("data.in", "r", stdin); 471 freopen("data.out", "w", stdout); 472 #endif 473 474 char ss[32]; 475 int p[] = { 476 44, 43, 42, 477 32, 31, 30, 478 20, 19, 18, 479 33, 21, 9, 0, 1, 2, 17, 29, 41, 53, 52, 51, 480 34, 22, 10, 3, 4, 5, 16, 28, 40, 50, 49, 48, 481 35, 23, 11, 6, 7, 8, 15, 27, 39, 47, 46, 45, 482 12, 13, 14, 483 24, 25, 26, 484 36, 37, 38 485 }; 486 487 init(); 488 int idx = 0; 489 rep(i, 0, 9) { 490 gets(ss); 491 int len = strlen(ss); 492 rep(i, 0, len) { 493 if (ss[i]=='0' || ss[i]=='1') 494 s[p[idx++]] = ss[i]; 495 } 496 } 497 assert(idx == 54); 498 solve(); 499 500 #ifndef ONLINE_JUDGE 501 printf("time = %ldms.\n", clock()); 502 #endif 503 504 return 0; 505 }
2.11 SPOJ IOPC1201
还是一个三阶魔方,给定一个操作序列,问最少执行多少次这个操作序列可以回到最初状态。题目看起来很来,实际很简单。一个操作序列其实就是从初始状态$p$到状态$q$的映射关系,可以将这个排列映射看成图,比如0->1->2->3->0。那么只要找到排列中的所有的环及其长度,这些长度的最小公倍数就是最优解了。这题挺简单的,做的人好少。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* SPOJ */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <bitset> 12 #include <algorithm> 13 #include <cstdio> 14 #include <cmath> 15 #include <ctime> 16 #include <cstring> 17 #include <climits> 18 #include <cctype> 19 #include <cassert> 20 #include <functional> 21 #include <iterator> 22 #include <iomanip> 23 using namespace std; 24 //#pragma comment(linker,"/STACK:102400000,1024000") 25 26 #define sti set<int> 27 #define stpii set<pair<int, int> > 28 #define mpii map<int,int> 29 #define vi vector<int> 30 #define pii pair<int,int> 31 #define vpii vector<pair<int,int> > 32 #define rep(i, a, n) for (int i=a;i<n;++i) 33 #define per(i, a, n) for (int i=n-1;i>=a;--i) 34 #define clr clear 35 #define pb push_back 36 #define mp make_pair 37 #define fir first 38 #define sec second 39 #define all(x) (x).begin(),(x).end() 40 #define SZ(x) ((int)(x).size()) 41 #define lson l, mid, rt<<1 42 #define rson mid+1, r, rt<<1|1 43 44 inline int lcm(int a, int b) { 45 int g = __gcd(a, b); 46 return a/g*b; 47 } 48 49 #define LEFT 0 50 #define FRONT 1 51 #define RIGHT 2 52 #define BACK 3 53 #define TOP 4 54 #define BOTTOM 5 55 int face[6][9] = { 56 /*Left*/ {9, 10, 11, 21, 22, 23, 33, 34, 35}, 57 /*Front*/ {12, 13, 14, 24, 25, 26, 36, 37, 38}, 58 /*Right*/ {15, 16, 17, 27, 28, 29, 39, 40, 41}, 59 /*Back*/ {18, 19, 20, 30, 31, 32, 42, 43, 44}, 60 /*Top*/ {0, 1, 2, 3, 4, 5, 6, 7, 8}, 61 /*Bottom*/ {45, 46, 47, 48, 49, 50, 51, 52, 53} 62 }; 63 64 const int maxl = 1015; 65 char ops[maxl]; 66 char s[56], d[56]; 67 int q; 68 vector<vi> vpos; 69 70 vi counter(const vi& p) { 71 int a[56], b[56]; 72 73 rep(i, 0, 54) a[i] = i; 74 rep(i, 0, 3) { 75 rep(j, 0, 54) b[j] = a[p[j]]; 76 memcpy(a, b, sizeof(b)); 77 } 78 79 return vi(a, a+54); 80 } 81 82 void init() { 83 int a[56], b[56]; 84 85 #define MOVE_ROW(des, src)\ 86 {\ 87 rep(i, 0, 3)\ 88 b[face[des][i]] = a[face[src][i]];\ 89 } 90 91 #define MOVE_ROW_(des, src)\ 92 {\ 93 rep(i, 6, 9)\ 94 b[face[des][i]] = a[face[src][i]];\ 95 } 96 97 #define MOVE_COL(des, src)\ 98 {\ 99 rep(i, 0, 3)\ 100 b[face[des][i*3]] = a[face[src][i*3]];\ 101 } 102 #define FORCE_MOVE(da, sa, db, sb, dc, sc)\ 103 {\ 104 b[da] = a[sa];\ 105 b[db] = a[sb];\ 106 b[dc] = a[sc];\ 107 } 108 109 110 // rotate U 111 { 112 113 rep(i, 0, 54) a[i] = i; 114 115 memcpy(b, a, sizeof(a)); 116 int* mf = face[TOP]; 117 rep(i, 0, 3) { 118 rep(j, 0, 3) { 119 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 120 } 121 } 122 MOVE_ROW(LEFT, FRONT); 123 MOVE_ROW(FRONT, RIGHT); 124 MOVE_ROW(RIGHT, BACK); 125 MOVE_ROW(BACK, LEFT); 126 127 vi vtmp(b, b+54); 128 vpos.pb(vtmp); 129 vpos.pb(counter(vtmp)); 130 } 131 132 // rotate R 133 { 134 rep(i, 0, 54) a[i] = i; 135 136 memcpy(b, a, sizeof(a)); 137 int* mf = face[RIGHT]; 138 rep(i, 0, 3) { 139 rep(j, 0, 3) { 140 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 141 } 142 } 143 FORCE_MOVE(face[TOP][2], face[FRONT][2], face[TOP][5], face[FRONT][5], face[TOP][8], face[FRONT][8]); // MOVE_COL(TOP, FRONT); 144 FORCE_MOVE(face[FRONT][2], face[BOTTOM][2], face[FRONT][5], face[BOTTOM][5], face[FRONT][8], face[BOTTOM][8]); // MOVE_COL(FRONT, BOTTOM); 145 FORCE_MOVE(face[BOTTOM][2], 42, face[BOTTOM][5], 30, face[BOTTOM][8], 18); // MOVE_COL(BOTTOM, BACK); 146 FORCE_MOVE(42, 2, 30, 5, 18, 8); // MOVE_COL(BACK, TOP); 147 148 vi vtmp(b, b+54); 149 vpos.pb(vtmp); 150 vpos.pb(counter(vtmp)); 151 } 152 153 // rotate F 154 { 155 rep(i, 0, 54) a[i] = i; 156 157 memcpy(b, a, sizeof(a)); 158 int* mf = face[FRONT]; 159 rep(i, 0, 3) { 160 rep(j, 0, 3) { 161 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 162 } 163 } 164 FORCE_MOVE(face[TOP][6], face[LEFT][8], face[TOP][7], face[LEFT][5], face[TOP][8], face[LEFT][2]); // MOVE_COL(TOP, LEFT); 165 FORCE_MOVE(face[RIGHT][0], face[TOP][6], face[RIGHT][3], face[TOP][7], face[RIGHT][6], face[TOP][8]); // MOVE_COL(RIGHT, TOP); 166 FORCE_MOVE(face[BOTTOM][0], face[RIGHT][6], face[BOTTOM][1], face[RIGHT][3], face[BOTTOM][2], face[RIGHT][0]); // MOVE_COL(BOTTOM, RIGHT); 167 FORCE_MOVE(face[LEFT][2], face[BOTTOM][0], face[LEFT][5], face[BOTTOM][1], face[LEFT][8], face[BOTTOM][2]); // MOVE_COL(LEFT, BOTTOM); 168 169 vi vtmp(b, b+54); 170 vpos.pb(vtmp); 171 vpos.pb(counter(vtmp)); 172 } 173 174 // rotate D 175 { 176 rep(i, 0, 54) a[i] = i; 177 178 memcpy(b, a, sizeof(a)); 179 int* mf = face[BOTTOM]; 180 rep(i, 0, 3) { 181 rep(j, 0, 3) { 182 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 183 } 184 } 185 MOVE_ROW_(FRONT, LEFT); 186 MOVE_ROW_(RIGHT, FRONT); 187 MOVE_ROW_(BACK, RIGHT); 188 MOVE_ROW_(LEFT, BACK); 189 190 vi vtmp(b, b+54); 191 vpos.pb(vtmp); 192 vpos.pb(counter(vtmp)); 193 } 194 195 // rotate L 196 { 197 rep(i, 0, 54) a[i] = i; 198 199 memcpy(b, a, sizeof(a)); 200 int* mf = face[LEFT]; 201 rep(i, 0, 3) { 202 rep(j, 0, 3) { 203 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 204 } 205 } 206 MOVE_COL(FRONT, TOP); 207 MOVE_COL(BOTTOM, FRONT); 208 FORCE_MOVE(20, 51, 32, 48, 44, 45); //MOVE_COL(BACK, BOTTOM); 209 FORCE_MOVE(0, 44, 3, 32, 6, 20); // MOVE_COL(TOP, BACK); 210 211 vi vtmp(b, b+54); 212 vpos.pb(vtmp); 213 vpos.pb(counter(vtmp)); 214 } 215 216 // rotate B 217 { 218 rep(i, 0, 54) a[i] = i; 219 220 memcpy(b, a, sizeof(a)); 221 int* mf = face[BACK]; 222 rep(i, 0, 3) { 223 rep(j, 0, 3) { 224 b[mf[i*3+j]] = a[mf[(2-j)*3+i]]; 225 } 226 } 227 FORCE_MOVE(face[LEFT][0], face[TOP][2], face[LEFT][3], face[TOP][1], face[LEFT][6], face[TOP][0]); // MOVE(LEFT, TOP); 228 FORCE_MOVE(face[TOP][0], face[RIGHT][2], face[TOP][1], face[RIGHT][5], face[TOP][2], face[RIGHT][8]); // MOVE(TOP, RIGHT); 229 FORCE_MOVE(face[RIGHT][2], 53, face[RIGHT][5], 52, face[RIGHT][8], 51); // MOVE(RIGHT, BOTTOM); 230 FORCE_MOVE(53, face[LEFT][6], 52, face[LEFT][3], 51, face[LEFT][0]); // MOVE(BOTTOM, LEFT); 231 232 vi vtmp(b, b+54); 233 vpos.pb(vtmp); 234 vpos.pb(counter(vtmp)); 235 } 236 } 237 238 void rotate(char c1, char c2='\0') { 239 static char uc[] = "URFDLB"; 240 241 int idx = strchr(uc, c1) - uc, n = 1; 242 idx <<= 1; 243 if (c2 == '2') { 244 n++; 245 } else if (c2 == '\'') { 246 idx += 1; 247 } 248 249 #ifndef ONLINE_JUDGE 250 assert(idx>=0 && idx<SZ(vpos)); 251 #endif 252 253 rep(i, 0, n) { 254 memcpy(d, s, sizeof(d)); 255 rep(j, 0, 54) 256 s[j] = d[vpos[idx][j]]; 257 } 258 } 259 260 bool visit[54]; 261 void solve() { 262 int len = strlen(ops); 263 int i = 0; 264 char c1, c2; 265 266 rep(i, 0, 54) s[i] = i; 267 while (i < len) { 268 c1 = ops[i]; 269 if (ops[i+1]=='\'' || ops[i+1]=='2') { 270 c2 = ops[i+1]; 271 ++i; 272 } else { 273 c2 = '\0'; 274 } 275 rotate(c1, c2); 276 ++i; 277 } 278 279 memset(visit, false, sizeof(visit)); 280 int ans = 1; 281 memcpy(d, s, sizeof(s)); 282 283 rep(i, 0, 54) { 284 if (visit[i]) continue; 285 int c = 1; 286 visit[i] = true; 287 288 int v = s[i]; 289 while (v != i) { 290 visit[v] = true; 291 ++c; 292 v = s[v]; 293 } 294 295 ans = lcm(ans, c); 296 } 297 298 printf("%d\n", ans); 299 } 300 301 int main() { 302 cin.tie(0); 303 ios::sync_with_stdio(false); 304 #ifndef ONLINE_JUDGE 305 freopen("data.in", "r", stdin); 306 freopen("data.out", "w", stdout); 307 #endif 308 309 int t; 310 311 init(); 312 scanf("%d", &t); 313 while (t--) { 314 scanf("%s", ops); 315 solve(); 316 } 317 318 #ifndef ONLINE_JUDGE 319 printf("time = %ldms.\n", clock()); 320 #endif 321 322 return 0; 323 } 324
3. 总结
rubik魔方问题主要涉及IDA*,双广,哈希等算法,算是比较基本,但是实现起来稍微麻烦的问题。因为这类问题做的人不多,单独拎出来做个系列。下个系列打算做crossword。当年携程比赛就是几道难易程度不等的crossword,还是蛮有趣的。