zoj 3736 Pocket Cube(2013亚洲区域赛 长沙站 K)


http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3736    


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.

zoj 3736 Pocket Cube(2013亚洲区域赛 长沙站 K)_第1张图片  zoj 3736 Pocket Cube(2013亚洲区域赛 长沙站 K)_第2张图片  zoj 3736 Pocket Cube(2013亚洲区域赛 长沙站 K)_第3张图片

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:

zoj 3736 Pocket Cube(2013亚洲区域赛 长沙站 K)_第4张图片


题意:就是一个2*2*2的魔方,问旋转不超过N(1<=N<=7)次最多能还原多少个面。
思路:因为最多只旋转7次,所以我们可以直接暴力搜索求最大,六个面顺时针逆时针一遍一共12中转法,不过因为只有2*2*2,所以对于相对的两个面,一个面顺时针旋转等价于另一个面逆时针转,所以可以缩减为6种旋转。只要把六种旋转的面的对应关系搞清楚就行了。可以打表,不过我没打,我用函数写的,顺时针逆时针可以化为一种旋转,一种转一次,一种转3次,详见代码。

#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
void up(int *a)
{
    int tmp=a[6];a[6]=a[7];a[7]=a[13];a[13]=a[12];a[12]=tmp;
    tmp=a[11];a[11]=a[2];a[2]=a[8];a[8]=a[17];a[17]=tmp;
    tmp=a[5];a[5]=a[3];a[3]=a[14];a[14]=a[16];a[16]=tmp;
}
void left(int *a)
{
    int tmp=a[11];a[11]=a[5];a[5]=a[4];a[4]=a[10];a[10]=tmp;
    tmp=a[0];a[0]=a[20];a[20]=a[16];a[16]=a[6];a[6]=tmp;
    tmp=a[2];a[2]=a[22];a[22]=a[18];a[18]=a[12];a[12]=tmp;
}
void front(int *a)
{
    int tmp=a[0];a[0]=a[2];a[2]=a[3];a[3]=a[1];a[1]=tmp;
    tmp=a[22];a[22]=a[5];a[5]=a[7];a[7]=a[9];a[9]=tmp;
    tmp=a[23];a[23]=a[4];a[4]=a[6];a[6]=a[8];a[8]=tmp;
}
int check(int a,int b,int c,int d)
{
    if(a==b&&a==c&&a==d)
    return 1;
    return 0;
}
int ans;
int getnum(int *a)
{
    int num=0;
    num+=check(a[0],a[1],a[2],a[3]);
    num+=check(a[4],a[5],a[10],a[11]);
    num+=check(a[6],a[7],a[12],a[13]);
    num+=check(a[8],a[9],a[14],a[15]);
    num+=check(a[16],a[17],a[18],a[19]);
    num+=check(a[20],a[21],a[22],a[23]);
    return num;
}
void (*(func)[3])(int *);
void dfs(int *a,int lef)
{
    ans=max(ans,getnum(a));
    if(ans==6)
    return;
    if(lef==0)
    return;
    int b[24];
    for(int i=0;i<3;i++)
    {
        memcpy(b,a,sizeof(int)*24);
        func[i](b);
        dfs(b,lef-1);
        func[i](b);func[i](b);
        dfs(b,lef-1);
    }
}
int main()
{
    //freopen("dd.txt","r",stdin);
    int n;
    func[0]=front;func[1]=left;func[2]=up;
    while(scanf("%d",&n)!=EOF)
    {
        int a[24];
        for(int i=0;i<24;i++)
        {
            scanf("%d",&a[i]);
        }

        ans=0;
        dfs(a,n);
        printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(ACM,ZOJ,亚洲)