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

题意:给你一个n*n的迷宫,其中0代表有一个人在这个位置,1代表墙,现在要求一个路线,使所有的人通过这个路线都可以走到迷宫的边界

注意当到达边界就相当于出去了不用继续走了,一个格子可以容纳很多人。

题解:先用BFS求出迷宫内部的点走到边界的最小步数(为了后面的IDA*剪枝),因为有很多状态,不好表示,所以可以想到用IDA*算法,在dfs的时候每次内部的点安同一个方向走,当某个点走到边界或遇见墙时不变,其他的点还是继续走。

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std; #define si1(a) scanf("%d",&a)
#define si2(a,b) scanf("%d%d",&a,&b)
#define sd1(a) scanf("%lf",&a)
#define sd2(a,b) scanf("%lf%lf",&a,&b)
#define ss1(s) scanf("%s",s)
#define pi1(a) printf("%d\n",a)
#define pi2(a,b) printf("%d %d\n",a,b)
#define mset(a,b) memset(a,b,sizeof(a))
#define forb(i,a,b) for(int i=a;i<b;i++)
#define ford(i,a,b) for(int i=a;i<=b;i++) typedef long long LL;
const int N=11;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-7; int n,depth;
int cnt;//表示不是边界点的个数
int x[101],y[101];//存放不是边界的点
int xh[N][N];//xh[i][j]表示ij到边界的最短距离,由BFS生成
char str[N][N];
int ans[1000];//存放方向
int dir[4][2]={0,1,-1,0,1,0,0,-1};//east north south west 按照字典序
bool flag; struct node
{
int x,y;
}w,e; bool bianjie(int x,int y)
{
if(x==0||x==n-1||y==0||y==n-1)
return true;
return false;
} bool inmap(int x,int y)
{
if(x>=0&&x<n&&y>=0&&y<n)
return true;
return false;
} void bfs()
{
queue<node> q;
q.push(w);
xh[w.x][w.y]=0;
while(!q.empty())
{
e=q.front();
q.pop(); for(int i=0;i<4;i++)
{
w.x=e.x+dir[i][0];
w.y=e.y+dir[i][1];
if(inmap(w.x,w.y)&&str[w.x][w.y]=='0')
{
if(xh[w.x][w.y]<=xh[e.x][e.y]) continue;
xh[w.x][w.y]=xh[e.x][e.y]+1;
q.push(w);
}
}
}
} int geth(int x[],int y[])//统计最大的距离
{
int ss=0;
forb(i,0,cnt) ss=max(ss,xh[x[i]][y[i]]);
return ss;
} void dfs(int tx[],int ty[],int de)
{
if(flag) return ;
if(geth(tx,ty)>de) return ;
if(de==0)//或者geth(tx,ty)==0
{
flag=true;
return ;
}
for(int i=0;i<4;i++)
{
int xx[101],yy[101];
for(int j=0;j<cnt;j++)//不是边界的点都按照i这个方向走
{
xx[j]=tx[j]; yy[j]=ty[j];
if(bianjie(xx[j],yy[j])) continue;
if(str[xx[j]+dir[i][0]][yy[j]+dir[i][1]]=='0')
{
xx[j]+=dir[i][0];
yy[j]+=dir[i][1];
}
}
ans[de]=i;
dfs(xx,yy,de-1);
if(flag) return;//这个地方一定要加上这一句,不然会被覆盖
}
} void IDA()
{
flag=false;
depth=geth(x,y);
while(1)
{
dfs(x,y,depth);
if(flag)
{
for(int i=depth;i>0;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");
}
break;
}
depth++;
}
} int main()
{
// freopen("input.txt","r",stdin);
int ca=0;
while(~si1(n))
{
forb(i,0,n) ss1(str[i]);
mset(xh,INF);//初始化为无穷大
cnt=0;
forb(i,0,n)
forb(j,0,n)
if(str[i][j]=='0')
{
w.x=i; w.y=j;
if(!bianjie(i,j))
{
x[cnt]=i;
y[cnt]=j;
cnt++;
}
else
bfs();//求出每个点要走出去的最小步数
}
if(ca++) printf("\n");
if(cnt==0||geth(x,y)==INF) {continue;}//都是边界点|走不出去的情况 IDA();
}
return 0 ;
}

HDU 1813 Escape from Tetris (IDA*)的更多相关文章

  1. HDU 1813 Escape from Tetris

    TMDTMD IDA*没跑了.什么是IDA*? 就是迭代深搜+A*估个价. 然而为什么调了一天? n<=2的时候我输出了东西.... 看了一天. #include<iostream> ...

  2. 【HDOJ】1813 Escape from Tetris

    bfs预处理一点到边界的最小距离,IDA*求出可行方案.注意按字典序初始化dir数组.并且存在中间点全为1,边界含0的可能性(wa了很多次).此时不输出任何命令. /* 1813 */ #includ ...

  3. HDU1813:Escape from Tetris(IDA)

    Problem Description 因为整日整夜地对着这个棋盘,Lele最终走火入魔.每天一睡觉.他就会梦到自己会被人被扔进一个棋盘中,一直找不到出路,然后从梦中惊醒.久而久之,Lele被搞得精神 ...

  4. ACM: hdu 1811 Rank of Tetris - 拓扑排序-并查集-离线

    hdu 1811 Rank of Tetris Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & % ...

  5. HDU 3533 Escape(大逃亡)

    HDU 3533 Escape(大逃亡) /K (Java/Others)   Problem Description - 题目描述 The students of the HEU are maneu ...

  6. HDU 3605 Escape (网络流,最大流,位运算压缩)

    HDU 3605 Escape (网络流,最大流,位运算压缩) Description 2012 If this is the end of the world how to do? I do not ...

  7. Hdu 3605 Escape (最大流 + 缩点)

    题目链接: Hdu 3605  Escape 题目描述: 有n个人要迁移到m个星球,每个星球有最大容量,每个人有喜欢的星球,问是否所有的人都能迁移成功? 解题思路: 正常情况下建图,不会爆内存,但是T ...

  8. hdu 1813(IDA*)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1813 思路:首先bfs预处理出‘0’到边界点最短距离,然后构造 h() 为所’0‘点逃离迷宫的最少步数 ...

  9. HDU 3605 Escape(状压+最大流)

    Escape Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Sub ...

随机推荐

  1. 执行eclipse,迅速failed to create the java virtual machine。

    它们必须在一排,否则会出现The Eclipse executable launcher was unable to locate its companion shared library的错误 打开 ...

  2. unity提取打包资源

    untiy打包资源是不可见的,在代码中须要www载入去提取,当然也有别的方法去提取打包资源.这对于非常久远的数据打包资源来说是个非常好的方法,由于太久远了就找不到了,仅仅能拿打包资源去提取,之前我写过 ...

  3. Android实现左右滑动效果

    本示例演示在Android中实现图片左右滑动效果.   关于滑动效果,在Android中用得比较多,本示例实现的滑动效果是使用ViewFlipper来实现的,当然也可以使用其它的View来实现.接下来 ...

  4. openssl 摘要和签名验证指令dgst使用详解

    1.信息摘要和数字签名概述 信息摘要:对数据进行处理,得到一段固定长度的结果,其特点输入: 1.输出长度固定.即输出长度和输入长度无关. 2.不可逆.即由输出数据理论上不能推导出输入数据 4.对输入数 ...

  5. C# 超级简单的Telnet (TcpClient)客户端

    基于Sockets 没什么好说的,代码说明了所有 using System; using System.Collections.Generic; using System.Linq; using Sy ...

  6. ie8 hack

    1.‘\9’: eg:.test { color/*\**/: blue\9 }.header {width:300px;} /* 所有浏览器*/.header {width/*\**/:330px\ ...

  7. 视图View

    视图UI层的HTML,JavaScript,Css等元素 asp.net mvc 框架支持惯例优先配置原则 视图路径:view/controller名/Action \view\home\index. ...

  8. 第一篇文章-VS的Local DB数据库连接失败,创建实例失败的解决方案

    用了很久的LocalDB了,不用装那么多的SQL组件感觉很不错,前不久调试代码碰到一个问题 ,VS突然就连接不上LocalDB了,琢磨了一下午,其实有个很简单的方法. 第一步,先找到SQL Local ...

  9. Windows命令行(DOS命令)教程–2 (转载) http://arch.pconline.com.cn//pcedu/rookie/basic/10111/15325_1.html

    二.符号约定 为了便于说明格式,这里我们使用了一些符号约定,它们是通用的: C: 盘符 Path 路径 Filename 文件名 .ext 扩展名 Filespec 文件标识符 [ ] 方括号中的项目 ...

  10. silverlight 打印

    加引用: using System.Windows.Printing; xaml文件里: //定义图片和文本打印变量  PrintDocument printImage; public BeginCo ...