POJ2286:The Rotation Game——题解

http://poj.org/problem?id=2286

题目大意:如图所示有一种玩具,每次可以拉动A-H的开关使得整个行(或列)向字母方向移动一位(如果移动到头的话则到行(列)尾部)

求使得中间八个方格内数字相同的移动顺序(移动次数最小且字典序最小)和最终中间八个方格内的数的个数。

————————————————————————

说好的学完IDA*之后独立做了一道题,全程没查题解一遍AC。

对于IDA*是什么不了解的,可以看我的置顶骑士精神那道题。

首先估价函数简单点处理就是8-中间相同的数的最大个数。

然后枚举最终答案跑dfs即可,没什么太大难度(就是代码实现吗!)

#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#include<map>
using namespace std;
int a[25];
char dir[8]={'A','B','C','D','E','F','G','H'};
int go[8][7]={{1,3,7,12,16,21,23},
          {2,4,9,13,18,22,24},
          {11,10,9,8,7,6,5},
          {20,19,18,17,16,15,14},
          {24,22,18,13,9,4,2},
          {23,21,16,12,7,3,1},
          {14,15,16,17,18,19,20},
          {5,6,7,8,9,10,11}};
int arc[8]={5,4,7,6,1,0,3,2};
int ans;
inline int h(){
    int t[4]={0},res=0;
    for(int i=7;i<=9;i++)t[a[i]]++;
    for(int i=12;i<=13;i++)t[a[i]]++;
    for(int i=16;i<=18;i++)t[a[i]]++;
    for(int i=1;i<=3;i++)res=max(res,t[i]);
    return 8-res;
}
inline void turn(int k){
    for(int i=1;i<7;i++){
        swap(a[go[k][i]],a[go[k][i-1]]);
    }
    return;
}
char realdir[101];
inline bool dfs(int step){
    if(step==ans){
        if(!h())return 1;
        return 0;
    }
    if(h()+step>ans)return 0;
    for(int i=0;i<8;i++){
        turn(i);
        if(dfs(step+1)){
            realdir[step]=i;
            return 1;
        }
        turn(arc[i]);
    }
    return 0;
}
int main(){
    while(scanf("%d",&a[1])!=EOF&&a[1]){
        for(int i=2;i<=24;i++)scanf("%d",&a[i]);
        for(ans=0;;ans++){
            if(dfs(0))break;
        }
        if(!ans)printf("No moves needed\n%d\n",a[12]);
        else{
            for(int i=0;i<ans;i++)printf("%c",dir[realdir[i]]);
            printf("\n%d\n",a[12]);
        }
    }
    return 0;
}

 

#include<cstdio>#include<cstring>#include<cctype>#include<iostream>#include<map>using namespace std;int a[25];char dir[8]={'A','B','C','D','E','F','G','H'};int go[8][7]={{1,3,7,12,16,21,23},      {2,4,9,13,18,22,24},      {11,10,9,8,7,6,5},      {20,19,18,17,16,15,14},      {24,22,18,13,9,4,2},      {23,21,16,12,7,3,1},      {14,15,16,17,18,19,20},      {5,6,7,8,9,10,11}};int arc[8]={5,4,7,6,1,0,3,2};int ans;inline int h(){    int t[4]={0},res=0;    for(int i=7;i<=9;i++)t[a[i]]++;    for(int i=12;i<=13;i++)t[a[i]]++;    for(int i=16;i<=18;i++)t[a[i]]++;    for(int i=1;i<=3;i++)res=max(res,t[i]);    return 8-res;}inline void turn(int k){    for(int i=1;i<7;i++){swap(a[go[k][i]],a[go[k][i-1]]);    }    return;}char realdir[101];inline bool dfs(int step){    if(step==ans){if(!h())return 1;return 0;}if(h()+step>ans)return 0;for(int i=0;i<8;i++){turn(i);if(dfs(step+1)){    realdir[step]=i;    return 1;}turn(arc[i]);    }    return 0;}int main(){    while(scanf("%d",&a[1])!=EOF&&a[1]){for(int i=2;i<=24;i++)scanf("%d",&a[i]);for(ans=0;;ans++){    if(dfs(0))break;}if(!ans)printf("No moves needed\n%d\n",a[12]);else{    for(int i=0;i<ans;i++)printf("%c",dir[realdir[i]]);    printf("\n%d\n",a[12]);}    }    return 0;}

posted @ 2017-12-10 10:20  luyouqi233  阅读(189)  评论(0编辑  收藏  举报