zoj 3726 Pocket Cube(搜索)

题意:有一个2×2×2的魔方,每一个小块上的颜色都不同,你现在最多能转魔方n次,m为魔方中一个面上的颜色全都相同的面的个数,问能转到的状态中m的最大值是多少。

思路:思路很简单,直接搜完所有状态,然后取个最大值就行了,但是写起来很烦,转啊转的都蒙了,gyf没事用纸做了个魔方给我看,按着这个魔方费了半天劲打了表……首先随便选一个面作为正面,那么对于当前状态来说一共有6种转法(怎么转的很容易能想出来),然后把转完以后哪个面对应哪个面算出来,打个表,剩下没什么难度,根据表直接搞就行了……


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
int n,ans;
int now[30],b[30];
int convert[6][24]=
{
    {1,3,0,2,23,22,4,5,6,7,10,11,12,13,14,15,16,17,18,19,20,21,9,8},
    {2,0,3,1,6,7,8,9,23,22,10,11,12,13,14,15,16,17,18,19,20,21,5,4},

    {0,7,2,13,4,5,6,17,14,8,10,11,12,19,15,9,16,21,18,23,20,1,22,3},
    {0,21,2,23,4,5,6,1,9,15,10,11,12,3,8,14,16,7,18,13,20,17,22,19},

    {0,1,8,14,4,3,7,13,17,9,10,2,6,12,16,15,5,11,18,19,20,21,22,23},
    {0,1,11,5,4,16,12,6,2,9,10,17,13,7,3,15,14,8,18,19,20,21,22,23}
};
int check()
{
    int rnt=0;
    bool flag=true;
    int color=now[0];
    for(int i=0;i<4;++i)
      if(now[i]!=color) flag=false;
    if(flag) rnt++;
    color=now[16];
    flag=true;
    for(int i=16;i<20;++i)
      if(now[i]!=color) flag=false;
    if(flag) rnt++;
    color=now[20];
    flag=true;
    for(int i=20;i<24;++i)
      if(now[i]!=color) flag=false;
    if(flag) rnt++;
    color=now[4];
    flag=true;
    for(int i=0;i<2;++i)
      if(now[4+i]!=color||now[4+i+6]!=color) flag=false;
    if(flag) rnt++;

    color=now[6];
    flag=true;
    for(int i=0;i<2;++i)
      if(now[6+i]!=color||now[6+i+6]!=color) flag=false;
    if(flag) rnt++;

    color=now[8];
    flag=true;
    for(int i=0;i<2;++i)
      if(now[8+i]!=color||now[8+i+6]!=color) flag=false;
    if(flag) rnt++;
    return rnt;
}
void rotate(int wh)
{
    for(int i=0;i<24;++i)
      b[i]=now[convert[wh][i]];
    for(int i=0;i<24;++i)
      now[i]=b[i];
}
void dfs(int step)
{
    if(step==n) return ;
    for(int i=0;i<6;++i)
    {
        rotate(i);
        int tmp=check();
        ans=max(ans,tmp);
        dfs(step+1);
        rotate(i^1);
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    while(~scanf("%d",&n))
    {
        for(int i=0;i<24;++i)
          scanf("%d",&now[i]);
        ans=check();
        dfs(0);
        printf("%d\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值