【搜索进阶】HDU 3459 Rubik 2×2×2

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3459
用IDA*写,很容易想到一个很不给力的A*剪枝:因为有一块始终不会改变,可以确定3个面的颜色,根据这3个面的颜色又可以确定另外3个面的颜色,也就是说最终状态是确定的,这样可以在递归到最后3层时稍微起到点作用。
#include<cstdio>
#include<cstring>
using namespace std; 
char maze[10][10];
void cvrX(){
    char tmp;
    tmp=maze[0][3]; maze[0][3]=maze[3][6];
        maze[3][6]=maze[4][3]; maze[4][3]=maze[2][3]; maze[2][3]=tmp;
    tmp=maze[1][3]; maze[1][3]=maze[2][6];
        maze[2][6]=maze[5][3]; maze[5][3]=maze[3][3]; maze[3][3]=tmp;
    tmp=maze[2][4]; maze[2][4]=maze[2][5];
        maze[2][5]=maze[3][5]; maze[3][5]=maze[3][4]; maze[3][4]=tmp;
} 
void cvrY(){
    char tmp;
    tmp=maze[2][0]; maze[2][0]=maze[2][6];
        maze[2][6]=maze[2][4]; maze[2][4]=maze[2][2]; maze[2][2]=tmp;
    tmp=maze[2][1]; maze[2][1]=maze[2][7];
        maze[2][7]=maze[2][5]; maze[2][5]=maze[2][3]; maze[2][3]=tmp;
    tmp=maze[0][2]; maze[0][2]=maze[0][3];
        maze[0][3]=maze[1][3]; maze[1][3]=maze[1][2]; maze[1][2]=tmp;
} 
void cvrZ(){
    char tmp;
    tmp=maze[2][1]; maze[2][1]=maze[1][3];
        maze[1][3]=maze[3][4]; maze[3][4]=maze[4][2]; maze[4][2]=tmp;
    tmp=maze[3][1]; maze[3][1]=maze[1][2];
        maze[1][2]=maze[2][4]; maze[2][4]=maze[4][3]; maze[4][3]=tmp;
    tmp=maze[2][2]; maze[2][2]=maze[2][3];
        maze[2][3]=maze[3][3]; maze[3][3]=maze[3][2]; maze[3][2]=tmp;
} 
bool check(){
    if(maze[0][3]!=maze[0][2]) return false;
    if(maze[1][2]!=maze[0][2]) return false;
    if(maze[1][3]!=maze[0][2]) return false; 
    if(maze[2][1]!=maze[2][0]) return false;
    if(maze[3][0]!=maze[2][0]) return false;
    if(maze[3][1]!=maze[2][0]) return false;  
    if(maze[2][3]!=maze[2][2]) return false;
    if(maze[3][2]!=maze[2][2]) return false;
    if(maze[3][3]!=maze[2][2]) return false;  
    if(maze[2][5]!=maze[2][4]) return false;
    if(maze[3][4]!=maze[2][4]) return false;
    if(maze[3][5]!=maze[2][4]) return false;  
    if(maze[2][7]!=maze[2][6]) return false;
    if(maze[3][6]!=maze[2][6]) return false;
    if(maze[3][7]!=maze[2][6]) return false;     
    if(maze[4][3]!=maze[4][2]) return false;
    if(maze[5][2]!=maze[4][2]) return false;
    if(maze[5][3]!=maze[4][2]) return false;
    return true;
}
int h(){
    int cnt=0;
    if(maze[5][3]!=maze[5][2]||maze[3][6]!=maze[3][7]) cnt++;
    if(maze[2][7]!=maze[3][7]||maze[2][0]!=maze[3][0]) cnt++;
    if(maze[3][0]!=maze[3][1]||maze[4][2]!=maze[5][2]) cnt++;
    return cnt;
} 
int deep;
char ans[100];
bool dfs(int d){    
    if(deep-d<=3&&d+h()>deep) return false;
    if(d==deep) return check();  
    cvrX();
    ans[d]='X';
    if(dfs(d+1)) return true;
    cvrX(); cvrX(); cvrX();
    cvrY();
    ans[d]='Y';
    if(dfs(d+1)) return true;
    cvrY(); cvrY(); cvrY();
    cvrZ();
    ans[d]='Z';
    if(dfs(d+1)) return true;
    cvrZ(); cvrZ(); cvrZ(); 
    return false;
} 
int main(){
    while(true){
        for(int i=0;i<6;i++){
            scanf("%s",maze[i]);
        }
        if(maze[0][2]=='.') break;
        deep=0;
        while(true){
            if(dfs(0)) break;
            deep++;
        }
        for(int i=0;i<deep;i++) putchar(ans[i]);
        puts("");
    }
    return 0;
}











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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值