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;
    }
    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;
}

 

转载于:https://www.cnblogs.com/luyouqi233/p/8016325.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值