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

来源:互联网 发布:js获取div name 编辑:程序博客网 时间:2024/04/28 07:38


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.

  

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:


题意:就是一个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;}