HDU 4801 Pocket Cube bfs

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:


 

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();
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值