hdu 4801 Pocket Cube

        题意:给出一个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 long

int 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值