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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值