传送门: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. Android中Service类onStartCommand

    Android开发的过程中,每次调用startService(Intent)的时候,都会调用该Service对象的onStartCommand(Intent,int,int)方法,然后在onStart ...

  2. display:inline和display:inline-block的区别

    先来一张图: 测试代码: <!DOCTYPE html> <html> <head> <style> #bb { overflow: hidden; b ...

  3. Qt串口通信

    1. Qt串口通信类QSerialPort 在Qt5的的更新中,新增了串口通信的相关接口类QSerialPort,这使得在开发者在使用Qt进行UI开发时,可以更加简单有效地实现串口通信的相关功能. 开 ...

  4. PowerDesigner Mysql 主键自增、初始值、字符集

    自增 在你所要设为自增型的键上(比如你的id)双击,弹出一个Column Properties对话框,右下角有一个Identify的选择框,选中它OK,就可以了. 再去查看Preview,就能看到AU ...

  5. C#如何获得本地电脑IP

    using System; using System.Collections.Generic; using System.Text; using System.Net;   //需要引用.Net命名空 ...

  6. NPOI导入导出Excel

    .net mvc利用NPOI导入导出excel 注意:如何导出的提交方式ajax导出是失效的! 解决方案是:js处理l两个表单的提交  代码:  第一步. 在页面里面加入2个隐藏的iframe, 如下 ...

  7. javascript作用域和作用域链

    1.作用域 作用域,它是指对某一变量和方法具有访问权限的代码空间.当我们在定义变量的时候,会定义两种变量,一种是在全局环境下定义的变量,叫全局变量,一种是在函数中定义的变量叫局部变量.全局变量的作用域 ...

  8. 第一次写博客,关于前端开发deMVC在js中的应用

    对前端MVC MVC分别是model.view.controller的缩写,模型.视图.控制器.这些更加偏向于后台,在以前MVC是只属于后台的.当然随着技术的进步,前端的大牛们将后台的一些东西应用于前 ...

  9. poj1159 dp(滚动数组优化)

    H - 简单dp 例题扩展 Crawling in process... Crawling failed Time Limit:3000MS     Memory Limit:65536KB     ...

  10. symfony2 表单

    正常情况下我还是更喜欢直接写表单而不是使用symfony内置的表单对象来穿件表单,但当我一个表单比较重要,需要csrf保护的时候 我会选择使用这种方法来表单. 官方文档有介绍一大堆通过类创建表单这里我 ...