Pocket Cube
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 816 Accepted Submission(s): 255
Problem Description
Pocket Cube is a 3-D combination puzzle. It is a 2 × 2 × 2 cube, which means it is constructed by 8 mini-cubes. For a combination of 2 × 2 mini-cubes which sharing a whole cube face, you can twist it 90 degrees in clockwise or counterclockwise direction, this twist operation is called one twist step.
Considering all faces of mini-cubes, there will be totally 24 faces painted in 6 different colors (Indexed from 0), and there will be exactly 4 faces painted in each kind of color. If 4 mini-cubes' faces of same color rely on same large cube face, we can call the large cube face as a completed face.
Now giving you an color arrangement of all 24 faces from a scrambled Pocket Cube, please tell us the maximum possible number of completed faces in no more than N twist steps.
Index of each face is shown as below:
Considering all faces of mini-cubes, there will be totally 24 faces painted in 6 different colors (Indexed from 0), and there will be exactly 4 faces painted in each kind of color. If 4 mini-cubes' faces of same color rely on same large cube face, we can call the large cube face as a completed face.
Now giving you an color arrangement of all 24 faces from a scrambled Pocket Cube, please tell us the maximum possible number of completed faces in no more than N twist steps.
Index of each face is shown as below:
Input
There will be several test cases. In each test case, there will be 2 lines. One integer N (1 ≤ N ≤ 7) in the first line, then 24 integers Ci separated by a single space in the second line. For index 0 ≤ i < 24, Ci is color of the corresponding face. We guarantee that the color arrangement is a valid state which can be achieved by doing a finite number of twist steps from an initial cube whose all 6 large cube faces are completed faces.
Output
For each test case, please output the maximum number of completed faces during no more than N twist step(s).
Sample Input
1 0 0 0 0 1 1 2 2 3 3 1 1 2 2 3 3 4 4 4 4 5 5 5 5 1 0 4 0 4 1 1 2 5 3 3 1 1 2 5 3 3 4 0 4 0 5 2 5 2
Sample Output
6 2
Source
题意:给出初始和目标魔方状态,问最短路。
思路:其实不难。 不过你要注意到只需要旋转三个面就可以了。
代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <string.h>
#include <cstring>
#include <time.h>
#include <stdio.h>
#include <queue>
#include <cmath>
#include <set>
#include <math.h>
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define rrep(i,b,a) for(int i = (b); i >= (a); --i)
#define clr(a,x) memset(a,(x),sizeof(a))
#define LL long long
#define eps 1e-10
#define zero(x) -eps < (x) && (x) < eps
using namespace std;
int face[6][4] =
{
{0,1,3,2},
{4,5,11,10},
{6,7,13,12},
{8,9,15,14},
{16,17,19,18},
{20,21,23,22}
};
int e[6][8] =
{
{9,8,7,6,5,4,22,23},
{0,2,6,12,16,18,20,22},
{2,3,8,14,17,16,11,5},
{23,21,19,17,13,7,3,1},
{10,11,12,13,14,15,21,20},
{18,19,15,9,1,0,4,10}
};
struct State
{
char a[24];
bool operator == (const State & st) const
{
rep(i,0,24)
if (a[i] != st.a[i]) return false;
return true;
}
bool operator < (const State & st) const
{
rep(i,0,24)
if (a[i] != st.a[i]) return a[i] < st.a[i];
return false;
}
void out() const
{
printf("\n ");
printf("%2c%2c\n",a[0],a[1]);
printf(" ");
printf("%2c%2c\n",a[2],a[3]);
rep(i,4,10) printf("%2c",a[i]);
puts("");
rep(i,10,16) printf("%2c",a[i]);
puts("");
printf(" ");
printf("%2c%2c\n",a[16],a[17]);
printf(" ");
printf("%2c%2c\n",a[18],a[19]);
printf(" ");
printf("%2c%2c\n",a[20],a[21]);
printf(" ");
printf("%2c%2c\n\n",a[22],a[23]);
}
int d;
int completeFace() const
{
int cnt = 0;
if (a[0] == a[1] && a[1] == a[2]
&& a[2] == a[3]) ++cnt;
if (a[6] == a[7] && a[7] == a[12]
&& a[12] == a[13]) ++cnt;
if (a[8] == a[9] && a[9] == a[14]
&& a[14] == a[15]) ++cnt;
if (a[4] == a[5] && a[5] == a[10]
&& a[10] == a[11]) ++cnt;
if (a[16] == a[17] && a[17] == a[18]
&& a[18] == a[19]) ++cnt;
if (a[20] == a[21] && a[21] == a[22]
&& a[22] == a[23]) ++cnt;
return cnt;
}
void Rotate(vector<char*>& face,vector<char*>& edge)
{
char ch = *face.back();
rrep(i,face.size()-1,1) {
*face[i] = *face[i-1];
}
*face[0] = ch;
char ch1 = *edge[6];
char ch2 = *edge[7];
rrep(i,edge.size()-1,2) {
*edge[i] = *edge[i-2];
}
*edge[0] = ch1;
*edge[1] = ch2;
}
}start;
int n;
void input()
{
rep(i,0,24) {
int c; scanf("%d",&c);
start.a[i] = c + '0';
}
}
inline int max(int a,int b) { return a > b ? a : b; }
void solve()
{
int ans = 0;
queue<State> q;
set<State> vis;
vis.insert(start);
start.d = 0;
q.push(start);
vector<char*> a,b;
State now,t;
while (q.size()) {
now = q.front(); q.pop();
// printf("%d %d\n",q.size(),now.d);
int h = now.completeFace();
if (h > ans) ans = h;
// if (h + (n - now.d) * 2 <= ans) continue;
if (ans == 6) break;
if (now.d >= n) continue;
int cnt = 0;
rep(i,0,3) {
a.clear(); b.clear();
t = now;
rep(j,0,4)
a.push_back(&t.a[face[i][j]]);
rep(j,0,8)
b.push_back(&t.a[e[i][j]]);
// now.out();
++t.d;
t.Rotate(a,b);
// t.out();
if (!vis.count(t)) {
q.push(t);
vis.insert(t);
++cnt;
}
a.clear(); b.clear();
t = now; ++t.d;
rrep(j,3,0)
a.push_back(&t.a[face[i][j]]);
rrep(j,7,0)
b.push_back(&t.a[e[i][j]]);
t.Rotate(a,b);
// now.out();
// t.out();
if (!vis.count(t)) {
q.push(t);
vis.insert(t);
++cnt;
}
}
//cout << cnt << endl;
}
printf("%d\n",ans);
}
int main()
{
#ifdef ACM
freopen("in.txt", "r", stdin);
#endif // AC
while (scanf("%d",&n)==1) {
input();
solve();
}
}