uva1343 IDA*

这题需要用数组记录每个block的位置。启发函数:d+wa(8-当前最多相同个数)>maxd直接退出

AC代码:

#include<cstdio>
#include<cstring> //IDA* 每次旋转最多只能增加一个相同的 启发函数:d+wa<=maxd
#include<algorithm>
using namespace std;
int block[24];
int pos[8][7]={
{0,2,6,11,15,20,22},{1,3,8,12,17,21,23},
{10,9,8,7,6,5,4},{19,18,17,16,15,14,13},
{23,21,17,12,8,3,1},{22,20,15,11,6,2,0},
{13,14,15,16,17,18,19},{4,5,6,7,8,9,10}
};
int goal[8]={6,7,8,11,12,15,16,17};
int dis[100000]; //记录步骤

void turn(int dir){
    int fir=block[pos[dir][0]];
    for(int i=0;i<6;++i){
        block[pos[dir][i]]=block[pos[dir][i+1]];
    }
    block[pos[dir][6]]=fir;
}
bool is_ok(){
    for(int i=0;i<7;++i){
        if(block[goal[i]]!=block[goal[i+1]]) return false;
    }
    return true;
}

bool dfs(int d,int maxd){
    if(is_ok()){  //找到答案
        if(!maxd) printf("No moves needed\n%d\n",block[6]);
        else {
            for(int i=0;i<maxd;++i)
                printf("%c",dis[i]+'A');
            printf("\n%d\n",block[6]);
        }
        return true;
    }
    //判断当前是否有可能在maxd下得到正确答案
    int a=0,b=0,c=0;
    for(int i=0;i<8;++i){
        if(block[goal[i]]==1) ++a;
        else if(block[goal[i]]==2) ++b;
        else if(block[goal[i]]==3) ++c;
    }
    int wa=8-max(max(a,b),c);
    if(d+wa>maxd) return false;

    int old[24];
    memcpy(old,block,sizeof(block));
    for(int i=0;i<8;++i){
        dis[d]=i;
        turn(i);
        if(dfs(d+1,maxd)) return true;
        memcpy(block,old,sizeof(old));
    }
    return false;
}
int main() {
    while(1){
        for(int i=0;i<24;++i) {
            scanf("%d",&block[i]);
            if(!block[i]) return 0;
        }
        for(int maxd=0;;++maxd){
            if(dfs(0,maxd)) break;
        }
    }
    return 0;
}

如有不当之处欢迎指出!

上一篇:Spring中使用到的设计模式


下一篇:SQL Server 基础 03 查询数据基础