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. gcc 编译 c++ 程序(转载)

    单个源文件生成可执行程序 下面是一个保存在文件 helloworld.cpp 中一个简单的 C++ 程序的代码: /* helloworld.cpp */ #include <iostream& ...

  2. 414 Third Maximum Number 第三大的数

    给定一个非空数组,返回此数组中第三大的数.如果不存在,则返回数组中最大的数.要求算法时间复杂度必须是O(n).示例 1:输入: [3, 2, 1]输出: 1解释: 第三大的数是 1.示例 2:输入: ...

  3. [转]ASP.net MVC 2 自定义模板来显示数据

    本文转自:http://blog.163.com/liaojunbo@126/blog/static/1394892972012113104653651/ 在ASP.net MVC 2中,一个很有意思 ...

  4. Oracle 的备份和恢复

    Oracle数据库有三种标准的备份方法,它们分别是导出/导入(EXP/IMP).热备份和冷备 份.导出备件是一种逻辑备份,冷备份和热备份是物理备份. 一. 导出/导入(Export/Import) 利 ...

  5. JAVA高级特性反射和注解

    反射: 枚举反射泛型注解.html34.3 KB 反射, 主要是指通过类加载, 动态的访问, 检测和修改类本身状态或行为的一种能力, 并能根据自身行为的状态和结果, 调整或修改应用所描述行为的状态和相 ...

  6. 锐动SDK针对游戏直播提出的解决方案

    方案架构 PC端视频直播与录播功能为游戏厂商宣传,玩家个人秀,大型电竞赛事提供完美的技术解决方案. 直播形式灵活多变不,同音源的选择,画面切换,游戏中嵌入摄像头丰,富解说画面.突出主播个人魅力与粉丝形 ...

  7. contact用法解析

    经典用法: mysql> select concat('11','22','33'); +------------------------+ | concat('11','22','33') | ...

  8. .net 操作xml --移除注释节点

    /// <summary> /// xml字符串转xml文档 忽略注释信息 /// </summary> /// <param name="sXml" ...

  9. C++11并发之std::mutex

    知识链接: C++11并发之std::thread   本文概要: 1. 头文件. 2.std::mutex. 3.std::recursive_mutex. 4.std::time_mutex. 5 ...

  10. 第一天 初识Python

    Python基础 一 编程语言     什么是编程语言?    上面提及的能够被计算机所识别的表达方式即编程语言,语言是沟通的介质,而编程语言是程序员与计算机沟通的介质.在编程的世界里,计算机更像是人 ...