HDU 1813 Escape from Tetris (IDA*)
传送门: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*)的更多相关文章
- HDU 1813 Escape from Tetris
TMDTMD IDA*没跑了.什么是IDA*? 就是迭代深搜+A*估个价. 然而为什么调了一天? n<=2的时候我输出了东西.... 看了一天. #include<iostream> ...
- 【HDOJ】1813 Escape from Tetris
bfs预处理一点到边界的最小距离,IDA*求出可行方案.注意按字典序初始化dir数组.并且存在中间点全为1,边界含0的可能性(wa了很多次).此时不输出任何命令. /* 1813 */ #includ ...
- HDU1813:Escape from Tetris(IDA)
Problem Description 因为整日整夜地对着这个棋盘,Lele最终走火入魔.每天一睡觉.他就会梦到自己会被人被扔进一个棋盘中,一直找不到出路,然后从梦中惊醒.久而久之,Lele被搞得精神 ...
- ACM: hdu 1811 Rank of Tetris - 拓扑排序-并查集-离线
hdu 1811 Rank of Tetris Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & % ...
- HDU 3533 Escape(大逃亡)
HDU 3533 Escape(大逃亡) /K (Java/Others) Problem Description - 题目描述 The students of the HEU are maneu ...
- HDU 3605 Escape (网络流,最大流,位运算压缩)
HDU 3605 Escape (网络流,最大流,位运算压缩) Description 2012 If this is the end of the world how to do? I do not ...
- Hdu 3605 Escape (最大流 + 缩点)
题目链接: Hdu 3605 Escape 题目描述: 有n个人要迁移到m个星球,每个星球有最大容量,每个人有喜欢的星球,问是否所有的人都能迁移成功? 解题思路: 正常情况下建图,不会爆内存,但是T ...
- hdu 1813(IDA*)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1813 思路:首先bfs预处理出‘0’到边界点最短距离,然后构造 h() 为所’0‘点逃离迷宫的最少步数 ...
- HDU 3605 Escape(状压+最大流)
Escape Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Sub ...
随机推荐
- 执行eclipse,迅速failed to create the java virtual machine。
它们必须在一排,否则会出现The Eclipse executable launcher was unable to locate its companion shared library的错误 打开 ...
- unity提取打包资源
untiy打包资源是不可见的,在代码中须要www载入去提取,当然也有别的方法去提取打包资源.这对于非常久远的数据打包资源来说是个非常好的方法,由于太久远了就找不到了,仅仅能拿打包资源去提取,之前我写过 ...
- Android实现左右滑动效果
本示例演示在Android中实现图片左右滑动效果. 关于滑动效果,在Android中用得比较多,本示例实现的滑动效果是使用ViewFlipper来实现的,当然也可以使用其它的View来实现.接下来 ...
- openssl 摘要和签名验证指令dgst使用详解
1.信息摘要和数字签名概述 信息摘要:对数据进行处理,得到一段固定长度的结果,其特点输入: 1.输出长度固定.即输出长度和输入长度无关. 2.不可逆.即由输出数据理论上不能推导出输入数据 4.对输入数 ...
- C# 超级简单的Telnet (TcpClient)客户端
基于Sockets 没什么好说的,代码说明了所有 using System; using System.Collections.Generic; using System.Linq; using Sy ...
- ie8 hack
1.‘\9’: eg:.test { color/*\**/: blue\9 }.header {width:300px;} /* 所有浏览器*/.header {width/*\**/:330px\ ...
- 视图View
视图UI层的HTML,JavaScript,Css等元素 asp.net mvc 框架支持惯例优先配置原则 视图路径:view/controller名/Action \view\home\index. ...
- 第一篇文章-VS的Local DB数据库连接失败,创建实例失败的解决方案
用了很久的LocalDB了,不用装那么多的SQL组件感觉很不错,前不久调试代码碰到一个问题 ,VS突然就连接不上LocalDB了,琢磨了一下午,其实有个很简单的方法. 第一步,先找到SQL Local ...
- Windows命令行(DOS命令)教程–2 (转载) http://arch.pconline.com.cn//pcedu/rookie/basic/10111/15325_1.html
二.符号约定 为了便于说明格式,这里我们使用了一些符号约定,它们是通用的: C: 盘符 Path 路径 Filename 文件名 .ext 扩展名 Filespec 文件标识符 [ ] 方括号中的项目 ...
- silverlight 打印
加引用: using System.Windows.Printing; xaml文件里: //定义图片和文本打印变量 PrintDocument printImage; public BeginCo ...