HDU 1667 The Rotation Game (A*迭代搜索)

题目大意:略

每次选择一个最大深度K,跑IDA*

估价函数H=8-中间8个格里出现次数最多的数的个数x,即把它填满这个数最少需要8-x次操作,如果dep+H>K,就跳出..

深搜的时候暴力修改,记录操作的方向,回溯再改回来就行了,根本不用把网格压进状态里嘛..

又水了一篇博客

#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define NN 2010
#define ll long long
#define uint unsigned int
#define ull unsigned long long
#define inf 0x3f3f3f3f
using namespace std;

int ans[NN];
int mp[20][20],tmp[10];
int xx[]={1,1,2,2,3,3,3,3,3,3,3,4,4,5,5,5,5,5,5,5,6,6,7,7};
int yy[]={3,5,3,5,1,2,3,4,5,6,7,3,5,1,2,3,4,5,6,7,3,5,3,5};
int sum[5],op[NN],num;
int esti()
{
    int x,y;
    sum[1]=sum[2]=sum[3]=0;
    x=xx[6],y=yy[6],sum[mp[x][y]]++;
    x=xx[7],y=yy[7],sum[mp[x][y]]++;
    x=xx[8],y=yy[8],sum[mp[x][y]]++;
    x=xx[11],y=yy[11],sum[mp[x][y]]++;
    x=xx[12],y=yy[12],sum[mp[x][y]]++;
    x=xx[15],y=yy[15],sum[mp[x][y]]++;
    x=xx[16],y=yy[16],sum[mp[x][y]]++;
    x=xx[17],y=yy[17],sum[mp[x][y]]++;
    return 8-max(sum[1],max(sum[2],sum[3]));
}
void A(){
    for(int i=0;i<7;i++)
        mp[i][3]=mp[i+1][3];
    mp[7][3]=mp[0][3],mp[0][3]=0;
}
void B(){
    for(int i=0;i<7;i++)
        mp[i][5]=mp[i+1][5];
    mp[7][5]=mp[0][5],mp[0][5]=0;
}
void C(){
    for(int i=8;i>1;i--)
        mp[3][i]=mp[3][i-1];
    mp[3][1]=mp[3][8],mp[3][8]=0;
}
void D(){
    for(int i=8;i>1;i--)
        mp[5][i]=mp[5][i-1];
    mp[5][1]=mp[5][8],mp[5][8]=0;
}
void E(){
    for(int i=8;i>1;i--)
        mp[i][5]=mp[i-1][5];
    mp[1][5]=mp[8][5],mp[8][5]=0;
}
void F(){
    for(int i=8;i>1;i--)
        mp[i][3]=mp[i-1][3];
    mp[1][3]=mp[8][3],mp[8][3]=0;
}
void G(){
    for(int i=0;i<7;i++)
        mp[5][i]=mp[5][i+1];
    mp[5][7]=mp[5][0],mp[5][0]=0;
}
void H(){
    for(int i=0;i<7;i++)
        mp[3][i]=mp[3][i+1];
    mp[3][7]=mp[3][0],mp[3][0]=0;
}

int dfs(int dep,int ma)
{
    if(esti()==0) return mp[3][3];
    if(dep>=ma) return 0;
    if(esti()>ma-dep) return 0;
    int ans;
    A();ans=dfs(dep+1,ma);F();
    if(ans){op[++num]=1;return ans;}
    B();ans=dfs(dep+1,ma);E();
    if(ans){op[++num]=2;return ans;}
    C();ans=dfs(dep+1,ma);H();
    if(ans){op[++num]=3;return ans;}
    D();ans=dfs(dep+1,ma);G();
    if(ans){op[++num]=4;return ans;}
    E();ans=dfs(dep+1,ma);B();
    if(ans){op[++num]=5;return ans;}
    F();ans=dfs(dep+1,ma);A();
    if(ans){op[++num]=6;return ans;}
    G();ans=dfs(dep+1,ma);D();
    if(ans){op[++num]=7;return ans;}
    H();ans=dfs(dep+1,ma);C();
    if(ans){op[++num]=8;return ans;}
    return 0;
}

int a[30];
int main()
{
    //freopen("t2.in","r",stdin);
    while(scanf("%d",&a[0])&&a[0]!=0)
    {
        ull S=0;num=0;
        mp[xx[0]][yy[0]]=a[0];
        for(int i=1;i<24;i++){
            scanf("%d",&a[i]);
            mp[xx[i]][yy[i]]=a[i];
        }
        int ans;
        ans=dfs(0,0);
        if(ans){
            printf("No moves needed\n%d\n",ans);
            continue;
        }
        for(int k=1;k<=500;k++){
            ans=dfs(0,k);
            if(ans){
                for(int i=num;i>=1;i--)
                    printf("%c",op[i]+‘A‘-1);
                puts("");
                printf("%d\n",ans);
                break;
            }
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/guapisolo/p/10011489.html

时间: 2024-11-10 22:08:36

HDU 1667 The Rotation Game (A*迭代搜索)的相关文章

hdu 1667 The Rotation Game ( IDA* )

题目大意: 给你一个"井"子状的board,对称的由24个方块组成,每个方块上有123三个数字中的一个.给你初始状态,共有八种变换方式,求字典序最小的最短的的变换路径使得,board中间的八个方块上数字相同.(建议看下题目中的图就懂啦). IDA*搜索. 我是干脆用结构体保存搜索状态(当然这样很占空间了,可能也耗时间,不过这题15s/150M的时空限制我也是醉了).保存一个board temp,一个搜索路径path,搜索深度n,以及一个内置的估值函数h().h()返回的是8减这八个方块

【HDOJ】1667 The Rotation Game

1. 题目描述有个#字型的条带,可以从横线或竖线进行循环移动,求通过各种移动最终使中心的8个字符全等的长度最短并相同长度字典序最小的操作序列.2. 基本思路24个数据,8种移动方式,数据量很小了,所以基本怎么玩儿都可以.需要注意的是因为横线竖线间有交点,所以每个条带的数据可能都是变化的.采用IDA*算法可解.所谓IDA*,就是不断对所求操作需要长度进行增加,然后不断当前长度是否存在可行的操作序列.判断是否存在可行操作序列的方法是深搜,这里需要注意去除先移动A紧接着移动F的类似情况.H函数的基本想

HDU 专题分类

[背包问题] 2602 Bone Collector 1114 Piggy-Bank 1203 I NEED A OFFER! 1171 Big Event in HDU 1059 Dividing 2844 Coins 2191 悼念512汶川大地震遇难同胞--珍惜现在,感恩生活 2159 FATE 1561 The more, The Better 1011 Starship Troopers 2639 Bone Collector II 3033 I love sneakers! 2955

POJ 2286 The Rotation Game 迭代搜索深度 + A* == IDA*

感觉这种算法还是比较局限的吧,重复搜索是一个不好的地方,而且需要高效的估值函数来进行强剪枝,这点比较困难. 迭代搜索深度是一个比较炫酷的搜索方式,不过有点拿时间换空间的感觉. 首先迭代深度比较搓的写法是,首先设置一个阀值MaxH,初始为最小值. 当在搜索深度Depth <= MaxH时找到解则此时为最优解,否则MaxH++,继续深搜. 另外一种比较吊的写法是二分搜索深度,若搜到则减小阀值,否则增大阀值. 总之,迭代深度搜索就是通过改变深搜的深度来寻找最优解,这样做的好处是省掉了BFS中状态标记所

HDU 4708 Rotation Lock Puzzle (贪心+模拟)

Rotation Lock Puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1668    Accepted Submission(s): 530 Problem Description Alice was felling into a cave. She found a strange door with a number

HDU 4708 Rotation Lock Puzzle

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4708 测试数据: 51 9 9 1 11 9 9 9 99 9 9 9 99 9 9 9 11 1 9 9 1 81 1 1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 using namespace std; 5 long long a[15][15]; 6 long long step,an

HDU 4708 Rotation Lock Puzzle(数学啊)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4708 Problem Description Alice was felling into a cave. She found a strange door with a number square matrix. These numbers can be rotated around the center clockwise or counterclockwise. A fairy came an

概率dp HDU 4405

Aeroplane chess Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4405 Appoint description:  System Crawler  (2014-10-18) Description Hzz loves aeroplane chess very much. The chess map contains N+

hdu 4405(概率dp简单题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4405 Aeroplane chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1535    Accepted Submission(s): 1050 Problem Description Hzz loves aeroplane