传送门: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. Linux是如何启动的

    今天早上在上操作系统课的时候,老师有提到计算机从按下开关键到最后由操作系统全然接管的整个过程. 只是讲课毕竟是十分抽象的,由于之前自己也看过这方面的内容,可是老是记不住,所以今天晚上就花了点时间,把& ...

  2. LoadRunner测试下载功能点脚本(方法一)

    性能需求:对系统某页面中,点击下载功能做并发测试,以获取在并发下载文件的情况下系统的性能指标. 备注:页面上点击下载时的文件可以是word.excel.pdf等. 问题1:录制完下载的场景后,发现脚本 ...

  3. Traceroute程序

    Linux和Unix中为traceroute,Windows中对应的是Tracert.如:Tracert www.baidu.com   输出为路由信息. C:\Users\Administrator ...

  4. VMware SphereESXi上安装虚拟机

    VMware SphereESXi上安装虚拟机 创建新虚拟机 此处以CentOS为例 注意:配置上传的系统文件位置及启动项

  5. 点击<a>标签,禁止页面自动跳到顶部的解决办法

       最近在开发一个小web的时候想给一个按钮增加一个弹出dialog功能,但是发现点击按钮后页面总是自动滚动至顶部,这点从用户体验上来讲是极其不爽的,于是开始跳进google大池寻求解决办法.网上的 ...

  6. iOS~~MD5加密

    // 一般加密 +(NSString *)md5String:(NSString *)str { const char *password=[str UTF8String]; unsigned cha ...

  7. RCP打包出来 运行 出现 JVM terminated.exit code = 13

    在建立PM.product,即打包时,没有添加相应的插件,导致无法运行

  8. No1_8.类和对象2_Java学习笔记_对象

    对象 /**** * *一.对象 *1.概念:对象是由类抽象出来的,对象可以操作类的属性和方法解决问题,了解对象的创建.操作和消亡很必要: *2.对象的创建: * a. new操作符创建:每实例化一个 ...

  9. Nutch+Hadoop集群搭建

    转载自:http://www.open-open.com/lib/view/open1328670771405.html 1.Apache Nutch    Apache Nutch是一个用于网络搜索 ...

  10. JSONP有什么作用

    1.解决跨域访问数据                 由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名.协议.端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求 ...