传送门: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++;}elsebfs();//求出每个点要走出去的最小步数}if(ca++)    printf("\n");if(cnt==0||geth(x,y)==INF)  {continue;}//都是边界点|走不出去的情况IDA();}return 0 ;
}

HDU 1813 Escape from Tetris (IDA*)相关推荐

  1. HDU1813:Escape from Tetris(IDA)

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

  2. hdu 1760 A New Tetris Game(搜索博弈)

    题目链接:hdu 1760 A New Tetris Game 题意: 给你一个矩阵,0表示可以放格子,现在给你2*2的格子,lele先放,问是否能赢. 题解: 爆搜.具体看代码 1 #include ...

  3. HDU 1811 Rank of Tetris(并查集按秩合并+拓扑排序)

    Rank of Tetris Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  4. hdu 1667 The Rotation Game(IDA*)

    题目大意: 有一个井字形结构的图形,每条线上7个数字(1,2,3,),每次可以从八个方向将一条线上的数字循环移动1个距离,问经过最少几次什么操作,可以将图形中间的八个方块变成同一种数字. 解题思路: ...

  5. HDU 1811 Rank of Tetris

    Rank of Tetris Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. hdu 1811 Rank of Tetris (并查集+拓扑排序)

    Problem - 1811 感觉这题的并查集以及拓扑排序并不难,但是做题的时候必须理解到矛盾(CONFLICT)与不确定(UNCERTAIN)直接的优先关系. 做这题的时候,构图什么的很简单,就是没 ...

  7. HDU [P3605] Escape

    二分图多重匹配 改进版的匈牙利,加入了一个cnt数组作为找到增广路的标志 本题有一个重要的优化见注释 #include <iostream> #include <cstdio> ...

  8. HDU - 3605 Escape(二分图多重匹配-网络流最大流+思维建边+状态压缩)

    题目链接:点击查看 题目大意:到世界末日了,现在人们要逃离去其他的星球,现在给出n个人以及m个星球,再给出每个人可以前往的星球,最后给出每个星球的容量,题目问最多能让多少个人逃离 题目分析:这个题读完 ...

  9. HDU - 3533 Escape(预处理+A*)

    题目链接:点击查看 题目大意:题意我感觉描述的很不清楚..是看网上其他大佬的博客总结来的,大意就是我们要从点(0,0)走到点(n,m),然后在一些地方设置了炮塔(炮塔视为墙),可以向一个方向周期性地发 ...

  10. HDU - 1811 Rank of Tetris 并查集 + 拓扑序 +me

    link 题意: 首先看到排名自然想到拓扑序,但是存在等于的情况,这就启发我们把等于的情况缩成一个点,让后在缩点后的图中进行拓扑即可. 对于不合法的情况当然是拓扑序没有遍历到应该遍历的点,所以只需要检 ...

最新文章

  1. Python 或将成为法国高中的官方编程教学语言
  2. html中放大镜案列,Canvas实现放大镜效果完整案例分析(附代码)
  3. Python的单引号、双引号和三引号的字符串
  4. MyCat学习:使用MySQL搭建主从复制(双主双从模式)
  5. linux 下mysql安装配置管理以及优化
  6. 有序序列中的i个最大数(算法导论思考题9-1)
  7. vue控制元素的隐藏和显示
  8. 行程日志2010-03-16沙井一村(1)
  9. excel进销存管理系统_美萍商业进销存软件—库存了如指掌
  10. 705. 设计哈希集合
  11. ZeroC Ice demo构建(继承Ice::Application类)
  12. SOCKET编程详解
  13. html5 svg 遮罩,HTML5 SVG和CSS3超酷文字遮罩动画特效
  14. UVA 1449 Dominating Patterns(AC自动机)
  15. 不要走开,有足够多的理由持续关注下去
  16. 2020十大科技趋势展望
  17. 【图像去噪】基于自适应小波阙值算法实现图像去噪附matlab代码
  18. 牵手腾讯视频,爱普生离年轻人更近了
  19. 戴尔服务器虚拟 介质,使用Dell R710 IDRAC挂载虚拟介质
  20. 【码云周刊第 28 期】计算机视觉时代的识图技术

热门文章

  1. Git图形化操作:Revert(恢复)本地的修改到上一个版本
  2. nginx access日志log_format优化之request_time 和upstream_response_time差别
  3. WireShark下载:官网、源码
  4. 六石管理学:座位可以考虑混排
  5. 不同CPU指令的指令集密度
  6. 热烈庆贺:一个月,由70名升级为60名!
  7. 软件基本功:变量局部化
  8. 编译器的不同,导致运行结果不一样
  9. 全网首发:LINUX OpenCV编译java/jar版本注意事项
  10. LINUX SHELL中使用sed匹配某一行并替换这一行的内容