n<=30 * m<=30 的地图上,0表示墙壁,1表示可以放箱子的空地。q<=500次询问,每次问:当空地上唯一没有放箱子的空格子在(ex,ey)时,把位于(sx,sy)的箱子移动到(tx,ty)的最小步数。

第一档:n<=10,m<=10,不加剪枝地乱搞??

第二档:n<=30,m<=30,q<=10,直接搜索,我觉得这60分够多了。。

所有档:

完成移动需要两个过程:空白格移动到指定箱子的周围(不能经过指定箱子),指定箱子在空白格的配合下逐渐逼近目标格子。

前者可以直接搜索得到,而后者比较麻烦。为了配合指定箱子,空白格必须时刻在指定箱子周围运动,也就是说,他会从指定箱子的上/下/左/右用最小代价移动到箱子的其他方位,然后让箱子朝那个方向前进一格。

这样的话,实际上是三元状态(x,y,z),(x,y)是当前指定箱子的坐标,z是空格子相对他的方位,这样一些状态之间走来走去,最终走道(tx,ty,上下左右),问最小代价。

可以发现状态之间走来走去的规则非常简单:一个是(x,y,上)转移成(x-1,y,下)这样的不同格子的相反空格方位的移动,另一种是(x,y,上)转移到(x,y,左)这样的同个格子、空格不同方位的转移。

同个格子不同方位间转移的代价可以bfs预处理,而,最后查最小代价只需要一次最短路。

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<math.h>
  4. #include<stdlib.h>
  5. #include<algorithm>
  6. #include<queue>
  7. //#include<iostream>
  8. using namespace std;
  9.  
  10. //预处理1:play[i][j][0-3][0-3]表示格子(i,j)的上0下1左2右3到上下左右的不经过格(i,j)的最小移动步数
  11. //最短路
  12.  
  13. bool isdigit(char c) {return c>='' && c<='';}
  14. int qread()
  15. {
  16. char c;int s=;while (!isdigit(c=getchar()));
  17. do s=s*+c-''; while (isdigit(c=getchar()));return s;
  18. }
  19.  
  20. const int inf=0x3f3f3f3f;
  21. int n,m,Q;
  22. int mp[][],play[][][][];
  23. const int dx[]={-,,,},dy[]={,,-,};
  24. struct qnode1
  25. {
  26. int x,y,d;
  27. }que1[*];int head,tail;bool vis1[][];
  28. void pre(int x,int y)
  29. {
  30. mp[x][y]=;
  31. for (int i=;i<;i++)
  32. for (int j=;j<;j++)
  33. {
  34. if (i==j) {play[x][y][i][j]=;continue;}
  35. if (x+dx[i]< || x+dx[i]>n || y+dy[j]< || y+dy[j]>m ||
  36. !mp[x+dx[i]][y+dy[i]] || !mp[x+dx[j]][y+dy[j]])
  37. {play[x][y][i][j]=inf;continue;}
  38. play[x][y][i][j]=inf;
  39. head=tail=;
  40. que1[tail].d=,que1[tail].x=x+dx[i],que1[tail++].y=y+dy[i];
  41. memset(vis1,,sizeof(vis1));vis1[x+dx[i]][y+dy[i]]=;
  42. while (head!=tail)
  43. {
  44. const int nx=que1[head].x,ny=que1[head].y,nd=que1[head].d;head++;
  45. if (nx==x+dx[j] && ny==y+dy[j])
  46. {
  47. play[x][y][i][j]=nd;
  48. break;
  49. }
  50. for (int k=;k<;k++)
  51. {
  52. int xx=nx+dx[k],yy=ny+dy[k];
  53. if (xx< || xx>n || yy< || yy>m || !mp[xx][yy] || vis1[xx][yy]) continue;
  54. vis1[xx][yy]=;
  55. que1[tail].x=xx,que1[tail].y=yy;que1[tail++].d=nd+;
  56. }
  57. }
  58. }
  59. mp[x][y]=;
  60. }
  61. int road(int sx,int sy,int tx,int ty)
  62. {
  63. if (tx==sx && ty==sy) return ;
  64. head=tail=;
  65. que1[tail].d=,que1[tail].x=sx,que1[tail++].y=sy;
  66. memset(vis1,,sizeof(vis1));vis1[sx][sy]=;
  67. while (head!=tail)
  68. {
  69. const int nx=que1[head].x,ny=que1[head].y,nd=que1[head].d;head++;
  70. if (nx==tx && ny==ty) return nd;
  71. for (int i=;i<;i++)
  72. {
  73. int xx=nx+dx[i],yy=ny+dy[i];
  74. if (xx< || xx>n || yy< || yy>m || !mp[xx][yy] || vis1[xx][yy]) continue;
  75. vis1[xx][yy]=;
  76. que1[tail].d=nd+;que1[tail].x=xx;que1[tail++].y=yy;
  77. }
  78. }
  79. return inf;
  80. }
  81. int dis[][][];bool vis[][][];
  82. struct qnode
  83. {
  84. int x,y,z,d;
  85. bool operator > (const qnode &b) const {return d>b.d;}
  86. };
  87. priority_queue<qnode,vector<qnode>,greater<qnode> > q;
  88. void work()
  89. {
  90. int ex=qread(),ey=qread(),sx=qread(),sy=qread(),tx=qread(),ty=qread();
  91. if (sx==tx && sy==ty)
  92. {
  93. puts("");
  94. return;
  95. }
  96. for (int i=;i<=n;i++)
  97. for (int j=;j<=m;j++)
  98. for (int k=;k<;k++)
  99. dis[i][j][k]=inf;
  100. for (int i=;i<;i++)
  101. {
  102. int xx=sx+dx[i],yy=sy+dy[i];
  103. if (xx< || xx>n || yy< || yy>m || !mp[xx][yy]) continue;
  104. mp[sx][sy]=;
  105. dis[sx][sy][i]=road(ex,ey,sx+dx[i],sy+dy[i]);
  106. mp[sx][sy]=;
  107. if (dis[sx][sy][i]<inf) q.push((qnode){sx,sy,i,dis[sx][sy][i]});
  108. }
  109. memset(vis,,sizeof(vis));
  110. while (!q.empty())
  111. {
  112. const int x=q.top().x,y=q.top().y,z=q.top().z,d=q.top().d;q.pop();
  113. if (vis[x][y][z]) continue;
  114. vis[x][y][z]=;
  115. if (z== && x> && mp[x-][y])
  116. if (dis[x-][y][]>d+)
  117. {
  118. dis[x-][y][]=d+;
  119. q.push((qnode){x-,y,,d+});
  120. }
  121. if (z== && x<n && mp[x+][y])
  122. if (dis[x+][y][]>d+)
  123. {
  124. dis[x+][y][]=d+;
  125. q.push((qnode){x+,y,,d+});
  126. }
  127. if (z== && y> && mp[x][y-])
  128. if (dis[x][y-][]>d+)
  129. {
  130. dis[x][y-][]=d+;
  131. q.push((qnode){x,y-,,d+});
  132. }
  133. if (z== && y<m && mp[x][y+])
  134. if (dis[x][y+][]>d+)
  135. {
  136. dis[x][y+][]=d+;
  137. q.push((qnode){x,y+,,d+});
  138. }
  139. for (int i=;i<;i++) if (i!=z)
  140. if (dis[x][y][i]>d+play[x][y][z][i])
  141. {
  142. dis[x][y][i]=d+play[x][y][z][i];
  143. q.push((qnode){x,y,i,d+play[x][y][z][i]});
  144. }
  145. }
  146. int ans=min(dis[tx][ty][],min(dis[tx][ty][],min(dis[tx][ty][],dis[tx][ty][])));
  147. printf("%d\n",(ans)>=inf?-:ans);
  148. }
  149. int main()
  150. {
  151. n=qread(),m=qread(),Q=qread();
  152. for (int i=;i<=n;i++)
  153. for (int j=;j<=m;j++)
  154. mp[i][j]=qread();
  155. for (int i=;i<=n;i++)
  156. for (int j=;j<=m;j++)
  157. if (mp[i][j])
  158. pre(i,j);
  159. while (Q--) work();
  160. return ;
  161. }

然而注意判断答案为0.。。。。。。没判被卡成65分 不如暴力

NOIP2013提高组D2T3 华容道的更多相关文章

  1. 洛谷P1979 [NOIP2013提高组Day2T3]华容道

    P1979 华容道 题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少 ...

  2. [NOIP2013 提高组] 华容道 P1979 洛谷

    [NOIP2013 提高组] 华容道 P1979 洛谷 强烈推荐,更好的阅读体验 经典题目:spfa+bfs+转化 题目大意: 给出一个01网格图,和点坐标x,y空格坐标a,b,目标位置tx,ty要求 ...

  3. 【数据结构】运输计划 NOIP2015提高组D2T3

    [数据结构]运输计划 NOIP2015提高组D2T3 >>>>题目 [题目描述] 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航 ...

  4. [NOIp2013提高组]积木大赛/[NOIp2018提高组]铺设道路

    [NOIp2013提高组]积木大赛/[NOIp2018提高组]铺设道路 题目大意: 对于长度为\(n(n\le10^5)\)的非负数列\(A\),每次可以选取一个区间\(-1\).问将数列清零至少需要 ...

  5. [NOIP2013提高组] CODEVS 3287 火车运输(MST+LCA)

    一开始觉得是网络流..仔细一看应该是最短路,再看数据范围..呵呵不会写...这道题是最大生成树+最近公共祖先.第一次写..表示各种乱.. 因为要求运输货物质量最大,所以路径一定是在最大生成树上的.然后 ...

  6. 【NOIP2013提高组T3】加分二叉树

    题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...

  7. NOIP2013 提高组day2 3 华容道 BFS

    描述 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面,华容道是否根本就无法完成,如果能完成,最少需要多少时间. 小 B 玩的华容道与经典的 ...

  8. [NOIP2013] 提高组 洛谷P1979 华容道

    题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时间. 小 ...

  9. 3537. 【NOIP2013提高组day2】华容道(搜索 + 剪枝)

    Problem 给出一个类似华容道的图.\(q\)次询问,每次给你起始点,终止点,空格位置,让你求最少步数 \(n,m\le 30, q\le 500\). Soultion 一道智障搜索题. 弱智想 ...

随机推荐

  1. 基于CentOS6.5下Suricata(一款高性能的网络IDS、IPS和网络安全监控引擎)的搭建(图文详解)(博主推荐)

    不多说,直接上干货! 为什么,要写这篇论文? 是因为,目前科研的我,正值研三,致力于网络安全.大数据.机器学习研究领域! 论文方向的需要,同时不局限于真实物理环境机器实验室的攻防环境.也不局限于真实物 ...

  2. ZOJ 3605Find the Marble(dp)

    ZOJ 3605 大体意思就是 找出随机选了K个交换后 石子在第i个罐子里的概率最大 也就是可能的总数最大 这样就可以写出递推方程 dp[i][j][k] += dp[i-1][e][k]; (0&l ...

  3. [转]Entity Framework and SQL Azure

    本文转自:https://msdn.microsoft.com/zh-cn/library/gg190738 Julie Lerman http://thedatafarm.com April 201 ...

  4. QT入门学习2

    QT获取窗口几何布局有2类函数: 1.包含框架:x().y().frameGemetry().pos().move()... 2.不包含框架:geometry().width().height().w ...

  5. VM virtualBox设置无缝全屏

    设置之前:

  6. Farseer.net轻量级ORM开源框架 V1.2.1版本升级消息

    提交版本V1.2.11.修复实体未设置主键时,无法找到主键ID字段,改为无主键时默认为"ID”字段2.新增:SqlServer2000Provider数据库驱动3.新增:DbContextI ...

  7. ansys中的.full文件中如何看刚度矩阵和质量矩阵(转)

    http://fffff-2001.blog.163.com/blog/static/15507529200722492917460 Q:请问ansys中的.full文件中如何看刚度矩阵和质量矩阵? ...

  8. Flask框架 之上下文、请求钩子与Flask_Script

    一.上下文 请求上下文:request与session 应用上下文:current_app与g:一次请求多个函数可以用它传参 @app.route("/") def index() ...

  9. 关于阻止Sublime Text更新弹窗提示

    使用Sublime Text有一段时间了,但每次重新打开都会弹出这家伙↑,很烦 网上查了查一些关闭弹窗的教程,大同小异,都说是打开Preferences --> Settings, 添加一行代码 ...

  10. jq进度条

    <!doctype html><html><head><meta charset="utf-8"><title>JQue ...