【ACM】魔方十一题

0. 前言
打了两年的百度之星,都没进决赛。我最大的感受就是还是太弱,总结起来就是:人弱就要多做题,人傻就要多做题。
题目还是按照分类做可能效果比较好,因此,就有了做几个系列的计划。这是系列中的第一个,解决OJ中有关魔方的问题。

1. 概述
魔方大概会涉及两类算法:搜索和模拟。这里的搜索方式一般是双广或者bfs+剪枝,因为双广基本上就可以把题目都解了,所以我也没去
考虑A*。我自身不会玩儿魔方,因此剪枝策略也就两种,不过效果还是很好的。模拟就相对简单,仅需要了解几种旋转的方式基本上是可解。
搜索过程中存在状态爆照问题,因为对于同一个魔方从不同的角度观察得到的抽象数据类型可能不尽相同,但是状态却等价。因此,
很多题需要找到所有可能等价的状态,这其实也是一堆排列。

写魔方旋转以及等价状态,我没有什么特别好的办法。不过由给定的顺时针,可以得到相应的逆时针;由正立状态及倒立状态的映射关系,可以
仅仅通过描述正立排列迅速得到倒立状态。

魔方问题的关键就在于剪枝,双广别写萎了,以及状态等价。

2. 题目
2.1 HDOJ 4801
这是一道2阶魔方,前面做过题解,请参考【HDOJ】4801 Pocket Cube 的几种解法和优化

2.2 HDOJ 5292
题目大意是给定任何的2阶魔方,需要判定该魔方能否复原。因为这个题目的case范围是$10^4$,所以直接在网上找的结论。具体缘由不清楚。

 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 }
View Code

2.3 HDOJ 3549
同样是一道2阶魔方,求由此时情况通过一定的操作序列实现复原。找到这样一个操作序列。
这题目是很早以前解掉的,基本算法是IDA*。启发式策略是至少经过多少次旋转能实现复原,这个策略是贪心的,实际操作可能多余这个H值。
因为2阶魔方大概10几步可能就解掉了,因此这算法性能还算不错。

  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 }
View Code

2.4 HDOJ 2691
这题目当时直接拿哈希做的,其实直接转换成longlong兴许还能容易点儿。算法是双广,两种剪枝策略:任何操作的不能与它的逆操作邻接;同一种操作至多进行2次,否则一定可以使用更少操作次数的逆操作实现。这题我使用了找到任何一种魔方的等价态。不使用这个能不能过不清楚。flip函数的就是如何通过正立排列映射为倒立的排列。

  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 }
View Code

2.5 HDOJ 1537 && POJ 1955
这道题目杭电上做的人不多,其实就是一道模拟,难在实现3阶魔方的旋转的映射排列。题目大意是给定魔方的状态及一串操作序列,求执行完后最终的魔方状态。
其中counter表示有给定的顺时针旋转,得到互逆的逆时针旋转。

  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 }
View Code

2.6 HDOJ 2168
写完了上一道题,这道题也基本写完了,重新映射一下输入的三阶魔方以及输出结果。这题就直接过了。注意这道题没有逆时针旋转。题目数据非常弱,完全不用优化。

  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 }
View Code

2.7 HDOJ 2953
这题是个2阶魔方,但是比前面的题目难,难点在于需要对初始魔方进行一个映射。题目是需要是讲魔方复原。但是每个面的颜色存在着不同的组合,这也导致最终魔方的状态不等价。
重新映射后就可以利用预处理的结果了,过预处理的由结束状态魔方执行7步操作可达状态。如果不在预处理状态中,那么bfs找到最优解。

  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 }
View Code

2.8 HDOJ 4397
 三阶魔方,增加了X、Y、Z轴的旋转,一道模拟题。大写表示顺时针旋转,小写表示逆时针旋转,判定按照指定序列旋转后魔方能否复原。

  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 }
View Code

2.9 POJ 1297
三阶魔方模拟,利用前面的代码稍微改改可以直接过了。

  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 }
View Code

2.10 POJ 3701
三阶魔方搜索,算法还是双广。但是这题wa了好几次,一定要注意读题,首先面1表示FRONT,同样旋转方式都是基于此前提下的,展开方式也是。因此,需要重新映射一下。这个题目不要使用状态等价,可以直接用longlong表示状态,因为$2^{54}$足够了,这里的1的个数一定为9。代码使用G++可以790ms过,C++一直超时。

  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 }
View Code

2.11 SPOJ IOPC1201
还是一个三阶魔方,给定一个操作序列,问最少执行多少次这个操作序列可以回到最初状态。题目看起来很来,实际很简单。一个操作序列其实就是从初始状态$p$到状态$q$的映射关系,可以将这个排列映射看成图,比如0->1->2->3->0。那么只要找到排列中的所有的环及其长度,这些长度的最小公倍数就是最优解了。这题挺简单的,做的人好少。

  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  
View Code


3. 总结
rubik魔方问题主要涉及IDA*,双广,哈希等算法,算是比较基本,但是实现起来稍微麻烦的问题。因为这类问题做的人不多,单独拎出来做个系列。下个系列打算做crossword。当年携程比赛就是几道难易程度不等的crossword,还是蛮有趣的。

posted on 2016-06-30 21:40  Bombe  阅读(1846)  评论(1编辑  收藏  举报

导航