HDU 1813 Escape from Tetris

http://acm.hdu.edu.cn/showproblem.php?pid=1813

IDA*。。。构造 h() 为所有点逃离迷宫的最少步数的最大值。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int dir[4][2]={{0,1},{-1,0},{1,0},{0,-1}};
int maze[22][33];

struct S
{
    bool a[33][22];
    S() { memset(a,0,sizeof a); }
}s;
int n,dep,ans[222],dis[333][333];

struct P {int x,y;P(int a=0,int b=0){x=a,y=b;}};;
#include<queue>
void bfs(int x,int y)
{
    queue<P> q;
    dis[x][y]=0;
    q.push(P(x,y));
    while(!q.empty())
    {
        P u=q.front(); q.pop();
        for(int d=0;d<4;d++)
        {
            P v(u.x+dir[d][0],u.y+dir[d][1]);
            int x=v.x,y=v.y;
            if(x<=0||x>=n-1||y<=0||y>=n-1||!maze[x][y]) continue;
            if(dis[x][y]>dis[u.x][u.y]+1)
            {
                dis[v.x][v.y]=min(dis[v.x][v.y],dis[u.x][u.y]+1);
                q.push(v);
            }
        }
    }
}
bool h(int d,S s)
{
    for(int i=1;i<n-1;i++)
        for(int j=1;j<n-1;j++)
    {
        if(!s.a[i][j]) continue;
        if(dis[i][j]+d>dep) return 0;
    }
    return 1;
}
bool dfs(int de,S u)
{
    if(!h(de,u)) return 0;
    if(de==dep) return 1;
    for(int d=0;d<4;d++)
    {
        S v;
        for(int i=1;i<n-1;i++)
            for(int j=1;j<n-1;j++)
        {
            if(!maze[i][j]) continue;
            int xx=i-dir[d][0], yy=j-dir[d][1];
            v.a[i][j]=u.a[xx][yy];
            xx=i+dir[d][0],yy=j+dir[d][1];
            if(maze[xx][yy]) continue;
            v.a[i][j]|=u.a[i][j];
        }
        ans[de]=d;
        if(dfs(de+1,v)) return 1;
    }
    return 0;
}
int main()
{
    bool ff=0;
    while(cin>>n&&n)
    {
       string in[33];   
        for(int i=0;i<n;i++) cin>>in[i];
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
        {
            maze[i][j]=(in[i][j]=='0');
            if(i*j&&i<n-1&&j<n-1) s.a[i][j]=maze[i][j];
        }
        if(n<=2) { puts(""); continue; }
        memset(dis,63,sizeof dis);
        for(int i=0;i<n;i++)
        {
            if(maze[0][i]) bfs(0,i);
            if(maze[i][0]) bfs(i,0);
            if(maze[n-1][i]) bfs(n-1,i);
            if(maze[i][n-1]) bfs(i,n-1);;
        }
        if(ff) puts("");  ff=1;
        dep=0;
        while(1) { if(dfs(0,s)) break; dep++; }
        for(int i=0;i<dep;i++)
        {
            if(ans[i]==0) puts("east");
            if(ans[i]==1) puts("north");
            if(ans[i]==2) puts("south");
            if(ans[i]==3) puts("west");
        }
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值