1. 题目描述
给定一个$2 \times 2 \times 2$的魔方,当某个面上的4个小块颜色均相同时,称这个面为complete。求对这个魔方进行$n \in [1,7]$次旋转(沿某个面顺时针或者逆时针)的过程中,求complete的面总和的最大值。魔方及索引如下图所示:
【HDOJ】4801 Pocket Cube 的几种解法和优化
【HDOJ】4801 Pocket Cube 的几种解法和优化

2. 基本思路及代码
解法一(MLE):
刚读过题,觉得挺简单的,时限10000ms还挺长的。需要搞清楚沿着某个面旋转后矩阵的元素是如何变化的。
就想到可以进行状态压缩$6^24 < 2^63$,因此将cube表示的矩阵可以使用long long压缩状态,然后再带上已经旋转的次数作为key,记忆化搜索就好了。代码如下:

  1 /* 4801 */
  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 LL __int64
 45 
 46 typedef struct {
 47     int st, t;
 48 } node_t;
 49 
 50 map<pair<LL,int>, int> tb;
 51 map<pair<LL,int>, int>::iterator iter;
 52 LL mask[24];
 53 int a[24];
 54 int n;
 55 int face[6][4] = {
 56     {0, 1, 2, 3},
 57     {4, 5, 10, 11},
 58     {6, 7, 12, 13},
 59     {8, 9, 14, 15},
 60     {16, 17, 18, 19},
 61     {20, 21, 22, 23}
 62 };
 63 
 64 int movf[6][12] = {
 65     {0,1,3,2,         22,23,9,8,7,6,5,4},
 66     {18,19,17,16,     20,21,15,14,13,12,11,10,},
 67     {4,5,11,10,        0,2,6,12,16,18,20,22},
 68     {9,8,14,15,        1,3,7,13,17,19,21,23},
 69     {6,7,12,13,        2,3,8,14,17,16,11,5},
 70     {22,23,21,20,    0,1,9,15,19,18,10,4}
 71 };
 72 int nxt[4];
 73 int unxt[4];
 74 
 75 void init() {
 76     mask[0] = 3;
 77     rep(i, 1, 24)
 78         mask[i] = mask[i-1] << 2;
 79 
 80     rep(i, 0, 4) {
 81         nxt[i] = (i+1) % 4;
 82         unxt[i] = (i-1+4)%4;
 83     }
 84 }
 85 
 86 LL zip(int *a) {
 87     LL ret = 0;
 88 
 89     per(i, 0, 24)
 90         ret = ret*6 + a[i];
 91 
 92     return ret;
 93 }
 94 
 95 void unzip(LL val, int *a) {
 96     rep(i, 0, 24) {
 97         a[i] = val % 6;
 98         val /= 6;
 99     }
100 }
101 
102 int calc(LL st) {
103     static int b[24];
104     int ret = 0;
105     unzip(st, b);
106 
107     rep(i, 0, 6) {
108         ++ret;
109         rep(j, 1, 4) {
110             if (b[face[i][j]] != b[face[i][0]]) {
111                 --ret;
112                 break;
113             }
114         }
115     }
116 
117     return ret;
118 }
119 
120 LL move_clock(LL st, int id) {
121     static int b[24];
122     static int c[24];
123     int i, j, *mf = movf[id];
124 
125     unzip(st, b);
126     memcpy(c, b, sizeof(c));
127 
128     for (i=0; i<4; ++i)
129         c[mf[nxt[i]]] = b[mf[i]];
130     for (i=0; i<4; ++i) {
131         c[mf[(nxt[i]<<1)+4]] = b[mf[(i<<1)+4]];
132         c[mf[(nxt[i]<<1|1)+4]] = b[mf[(i<<1|1)+4]];
133     }
134 
135     return zip(c);
136 }
137 
138 LL move_unclock(LL st, int id) {
139     static int b[24];
140     static int c[24];
141     int i, j, *mf = movf[id];
142 
143     unzip(st, b);
144     memcpy(c, b, sizeof(c));
145 
146     for (i=0; i<4; ++i)
147         c[mf[unxt[i]]] = b[mf[i]];
148     for (i=0; i<4; ++i) {
149         c[mf[(unxt[i]<<1)+4]] = b[mf[(i<<1)+4]];
150         c[mf[(unxt[i]<<1|1)+4]] = b[mf[(i<<1|1)+4]];
151     }
152 
153     return zip(c);
154 }
155 
156 
157 int dfs(LL st, int n) {
158     pair<LL,int> p = mp(st, n);
159 
160     iter = tb.find(p);
161     if (iter != tb.end())
162         return iter->sec;
163     
164     int ret = 0;
165     
166     ret = calc(st);
167     
168     LL nst;
169     
170     #ifndef ONLINE_JUDGE
171     int b[24];
172     #endif
173     
174     if (n) {
175         rep(i, 0, 6) {
176             nst = move_clock(st, i);
177             #ifndef ONLINE_JUDGE
178                 unzip(nst, b);
179                 rep(j, 0, 24)
180                     printf("%d ", b[j]);
181                 putchar('\n');
182             #endif
183             ret = max(ret, dfs(nst, n-1));
184             nst = move_unclock(st, i);
185             #ifndef ONLINE_JUDGE
186                 unzip(nst, b);
187                 rep(j, 0, 24)
188                     printf("%d ", b[j]);
189                 putchar('\n');
190             #endif
191             ret = max(ret, dfs(nst, n-1));
192         }
193     }
194 
195     tb[p] = ret;
196 
197     return ret;
198 }
199 
200 void solve() {
201     LL st = zip(a);
202     int ans = 0;
203 
204     // tb.clr();
205 
206     ans = dfs(st, n);
207 
208     printf("%d\n", ans);
209 }
210 
211 int main() {
212     ios::sync_with_stdio(false);
213     #ifndef ONLINE_JUDGE
214         freopen("data.in", "r", stdin);
215         freopen("data.out", "w", stdout);
216     #endif
217 
218     init();
219     while (scanf("%d", &n)!=EOF) {
220         rep(i, 0, 24)
221             scanf("%d", &a[i]);
222         solve();
223     }
224 
225     #ifndef ONLINE_JUDGE
226         printf("time = %d.\n", (int)clock());
227     #endif
228 
229     return 0;
230 }
View Code

相关文章:

  • 2022-12-23
  • 2021-05-23
  • 2022-12-23
  • 2021-06-09
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-25
  • 2021-08-07
  • 2021-11-07
相关资源
相似解决方案