hdu 4801 Pocket Cube

来源:互联网 发布:域名劫持修复工具 编辑:程序博客网 时间:2024/05/01 17:32

        题意:给出一个Pocket Cube的状态,问n步(每步只能顺时针转90度)最多能还原几个面。

        思路:作为一个Cuber,看到这种题非常激动,凭着自己对魔方突(yi)破(dian)天(dian)际的理解A掉了。。。这里我用的是dfs+回溯,因为把魔方的状态转成int的哈希不是那么好写,所以没有写状态判重,直接回溯解决。然后,其实六个面的旋转只需要写三个函数,因为相对的面的旋转其实是等效的。

        写这个题要非常细心。。因为里面有很多常数。。


#include<iostream>#include<cmath>#include<queue>#include<vector>#include<algorithm>#include<string.h>#include<cstdio>using namespace std;#define ll long longint judge(int* a){    int re=0;    if(a[0]==a[1]&&a[0]==a[2]&&a[0]==a[3])re++;    if(a[4]==a[5]&&a[4]==a[10]&&a[4]==a[11])re++;    if(a[6]==a[7]&&a[6]==a[12]&&a[6]==a[13])re++;    if(a[16]==a[17]&&a[16]==a[18]&&a[16]==a[19])re++;    if(a[8]==a[9]&&a[8]==a[14]&&a[8]==a[15])re++;    if(a[20]==a[21]&&a[20]==a[22]&&a[20]==a[23])re++;    return re;}int a[24];void r(){    int b[24];    memcpy(b,a,sizeof(a));    a[1]=b[7];    a[3]=b[13];    a[7]=b[17];    a[13]=b[19];    a[17]=b[21];    a[19]=b[23];    a[21]=b[1];    a[23]=b[3];    a[8]=b[14];    a[9]=b[8];    a[15]=b[9];    a[14]=b[15];}void u(){    int b[24];    memcpy(b,a,sizeof(a));    a[4]=b[6];    a[5]=b[7];    a[6]=b[8];    a[7]=b[9];    a[8]=b[23];    a[9]=b[22];    a[23]=b[4];    a[22]=b[5];    a[0]=b[2];    a[1]=b[0];    a[3]=b[1];    a[2]=b[3];}void f(){    int b[24];    memcpy(b,a,sizeof(a));    a[2]=b[11];    a[3]=b[5];    a[8]=b[2];    a[14]=b[3];    a[17]=b[8];    a[16]=b[14];    a[11]=b[17];    a[5]=b[16];    a[6]=b[12];    a[7]=b[6];    a[13]=b[7];    a[12]=b[13];}int n;int ans;void dfs(int d){    if(d>n||ans==6)return;//剪枝,因为最多6面    ans=max(ans,judge(a));    u();    dfs(d+1);    u();    u();    u();        r();    dfs(d+1);    r();    r();    r();    f();    dfs(d+1);    f();    f();    f();//相当于d    u();    u();    u();    dfs(d+1);    u();//相当于l    r();    r();    r();    dfs(d+1);    r();//相当于b    f();    f();    f();    dfs(d+1);    f();}int main(){    while(cin>>n){        ans=0;        for(int i=0;i<24;i++){            scanf("%d",&a[i]);        }        dfs(0);        cout<<ans<<endl;    }    return 0;}


0 0