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 ...
随机推荐
- Android中Service类onStartCommand
Android开发的过程中,每次调用startService(Intent)的时候,都会调用该Service对象的onStartCommand(Intent,int,int)方法,然后在onStart ...
- display:inline和display:inline-block的区别
先来一张图: 测试代码: <!DOCTYPE html> <html> <head> <style> #bb { overflow: hidden; b ...
- Qt串口通信
1. Qt串口通信类QSerialPort 在Qt5的的更新中,新增了串口通信的相关接口类QSerialPort,这使得在开发者在使用Qt进行UI开发时,可以更加简单有效地实现串口通信的相关功能. 开 ...
- PowerDesigner Mysql 主键自增、初始值、字符集
自增 在你所要设为自增型的键上(比如你的id)双击,弹出一个Column Properties对话框,右下角有一个Identify的选择框,选中它OK,就可以了. 再去查看Preview,就能看到AU ...
- C#如何获得本地电脑IP
using System; using System.Collections.Generic; using System.Text; using System.Net; //需要引用.Net命名空 ...
- NPOI导入导出Excel
.net mvc利用NPOI导入导出excel 注意:如何导出的提交方式ajax导出是失效的! 解决方案是:js处理l两个表单的提交 代码: 第一步. 在页面里面加入2个隐藏的iframe, 如下 ...
- javascript作用域和作用域链
1.作用域 作用域,它是指对某一变量和方法具有访问权限的代码空间.当我们在定义变量的时候,会定义两种变量,一种是在全局环境下定义的变量,叫全局变量,一种是在函数中定义的变量叫局部变量.全局变量的作用域 ...
- 第一次写博客,关于前端开发deMVC在js中的应用
对前端MVC MVC分别是model.view.controller的缩写,模型.视图.控制器.这些更加偏向于后台,在以前MVC是只属于后台的.当然随着技术的进步,前端的大牛们将后台的一些东西应用于前 ...
- poj1159 dp(滚动数组优化)
H - 简单dp 例题扩展 Crawling in process... Crawling failed Time Limit:3000MS Memory Limit:65536KB ...
- symfony2 表单
正常情况下我还是更喜欢直接写表单而不是使用symfony内置的表单对象来穿件表单,但当我一个表单比较重要,需要csrf保护的时候 我会选择使用这种方法来表单. 官方文档有介绍一大堆通过类创建表单这里我 ...