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预处理,而,最后查最小代价只需要一次最短路。

 #include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
//#include<iostream>
using namespace std; //预处理1:play[i][j][0-3][0-3]表示格子(i,j)的上0下1左2右3到上下左右的不经过格(i,j)的最小移动步数
//最短路 bool isdigit(char c) {return c>='' && c<='';}
int qread()
{
char c;int s=;while (!isdigit(c=getchar()));
do s=s*+c-''; while (isdigit(c=getchar()));return s;
} const int inf=0x3f3f3f3f;
int n,m,Q;
int mp[][],play[][][][];
const int dx[]={-,,,},dy[]={,,-,};
struct qnode1
{
int x,y,d;
}que1[*];int head,tail;bool vis1[][];
void pre(int x,int y)
{
mp[x][y]=;
for (int i=;i<;i++)
for (int j=;j<;j++)
{
if (i==j) {play[x][y][i][j]=;continue;}
if (x+dx[i]< || x+dx[i]>n || y+dy[j]< || y+dy[j]>m ||
!mp[x+dx[i]][y+dy[i]] || !mp[x+dx[j]][y+dy[j]])
{play[x][y][i][j]=inf;continue;}
play[x][y][i][j]=inf;
head=tail=;
que1[tail].d=,que1[tail].x=x+dx[i],que1[tail++].y=y+dy[i];
memset(vis1,,sizeof(vis1));vis1[x+dx[i]][y+dy[i]]=;
while (head!=tail)
{
const int nx=que1[head].x,ny=que1[head].y,nd=que1[head].d;head++;
if (nx==x+dx[j] && ny==y+dy[j])
{
play[x][y][i][j]=nd;
break;
}
for (int k=;k<;k++)
{
int xx=nx+dx[k],yy=ny+dy[k];
if (xx< || xx>n || yy< || yy>m || !mp[xx][yy] || vis1[xx][yy]) continue;
vis1[xx][yy]=;
que1[tail].x=xx,que1[tail].y=yy;que1[tail++].d=nd+;
}
}
}
mp[x][y]=;
}
int road(int sx,int sy,int tx,int ty)
{
if (tx==sx && ty==sy) return ;
head=tail=;
que1[tail].d=,que1[tail].x=sx,que1[tail++].y=sy;
memset(vis1,,sizeof(vis1));vis1[sx][sy]=;
while (head!=tail)
{
const int nx=que1[head].x,ny=que1[head].y,nd=que1[head].d;head++;
if (nx==tx && ny==ty) return nd;
for (int i=;i<;i++)
{
int xx=nx+dx[i],yy=ny+dy[i];
if (xx< || xx>n || yy< || yy>m || !mp[xx][yy] || vis1[xx][yy]) continue;
vis1[xx][yy]=;
que1[tail].d=nd+;que1[tail].x=xx;que1[tail++].y=yy;
}
}
return inf;
}
int dis[][][];bool vis[][][];
struct qnode
{
int x,y,z,d;
bool operator > (const qnode &b) const {return d>b.d;}
};
priority_queue<qnode,vector<qnode>,greater<qnode> > q;
void work()
{
int ex=qread(),ey=qread(),sx=qread(),sy=qread(),tx=qread(),ty=qread();
if (sx==tx && sy==ty)
{
puts("");
return;
}
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
for (int k=;k<;k++)
dis[i][j][k]=inf;
for (int i=;i<;i++)
{
int xx=sx+dx[i],yy=sy+dy[i];
if (xx< || xx>n || yy< || yy>m || !mp[xx][yy]) continue;
mp[sx][sy]=;
dis[sx][sy][i]=road(ex,ey,sx+dx[i],sy+dy[i]);
mp[sx][sy]=;
if (dis[sx][sy][i]<inf) q.push((qnode){sx,sy,i,dis[sx][sy][i]});
}
memset(vis,,sizeof(vis));
while (!q.empty())
{
const int x=q.top().x,y=q.top().y,z=q.top().z,d=q.top().d;q.pop();
if (vis[x][y][z]) continue;
vis[x][y][z]=;
if (z== && x> && mp[x-][y])
if (dis[x-][y][]>d+)
{
dis[x-][y][]=d+;
q.push((qnode){x-,y,,d+});
}
if (z== && x<n && mp[x+][y])
if (dis[x+][y][]>d+)
{
dis[x+][y][]=d+;
q.push((qnode){x+,y,,d+});
}
if (z== && y> && mp[x][y-])
if (dis[x][y-][]>d+)
{
dis[x][y-][]=d+;
q.push((qnode){x,y-,,d+});
}
if (z== && y<m && mp[x][y+])
if (dis[x][y+][]>d+)
{
dis[x][y+][]=d+;
q.push((qnode){x,y+,,d+});
}
for (int i=;i<;i++) if (i!=z)
if (dis[x][y][i]>d+play[x][y][z][i])
{
dis[x][y][i]=d+play[x][y][z][i];
q.push((qnode){x,y,i,d+play[x][y][z][i]});
}
}
int ans=min(dis[tx][ty][],min(dis[tx][ty][],min(dis[tx][ty][],dis[tx][ty][])));
printf("%d\n",(ans)>=inf?-:ans);
}
int main()
{
n=qread(),m=qread(),Q=qread();
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
mp[i][j]=qread();
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
if (mp[i][j])
pre(i,j);
while (Q--) work();
return ;
}

然而注意判断答案为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. ASP.Net 控件

    简单控件 Label -作用是显示文字,编译后元素是Span 1.文本类 边框: BorderColor 边框颜色 BordersTyle 边框样式 BorderWidth 边框粗细 Literal- ...

  2. ES之值类型以及堆和栈

    ES的数据类型: 原始类型(值存在栈内存中): Number.String Boolean.undefined.null charAt(index)返回该index所在的字节,charCodeAt(i ...

  3. Java线程-线程、程序、进程的基本概念

    线程 与进程相似,但线程是一个比进程更小的执行单位.一个进程在其执行的过程中可以产生多个线程. 与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间 ...

  4. web 自动化测试 selenium基础到应用(目录)

    第一章   自动化测试前提及整体介绍 1-1功能测试和自动化测试的区别 1-2自动化测试流程有哪些 1-3自动化测试用例和手工用例的区别 1-4 自动化测试用例编写 1-5 selenium的优势以及 ...

  5. asterisk-java ami3 属性改变监听

    asteriskServer.addAsteriskServerListener(new AsteriskListenerInit());//服务属性监听会自动连接服务 实现AsteriskServe ...

  6. 乐视max2 刷入第三方recovery 然后刷入root 包 root

    乐视max2 刷入第三方recovery 然后刷入root 包 root 第三方recovery:为奇兔 刷入root 包 https://share.weiyun.com/ddcdd5ea83956 ...

  7. CentOS 6.4 php-fpm 添加service 添加平滑启动/重启

    nginx通过FastCGI运行PHP比Apache包含PHP环境有明显的优势,最近有消息称,PHP5.4将很有可能把PHP-FPM补丁包含在内核里,nginx服务器平台上运行PHP将更加轻松,下面我 ...

  8. 迅为IMX6UL开发板

    迅为iMX6UL开发板采用核心板加底板形式,核心板使用邮票孔方式连接,牢固耐用.处理器ARM®Cortex®-A7内核,运行速度高达528 MHz.512MDDR内存,8G EMMC存储,板截双网口, ...

  9. Google浏览器开发者工具:CSSViewer(一个Css查看器)

    CSSViewer的简介 CSSViewer是一款可以帮助用户快速查看当前的网页元素的CSS属性的谷歌浏览器插件,在Chrome中安装了CSSViewer插件以后,用户就可以在设计网页的时候,快速地模 ...

  10. Jmeter之定时器

    转自:https://www.cnblogs.com/imyalost/p/6004678.html 一.定时器的作用域 1.定时器是在每个sampler(采样器)之前执行的,而不是之后(无论定时器位 ...