题目描述

VRI(Voltron 机器人学会)的工程师建造了 n 个机器人。任意两个兼容的机 器人站在同一个格子时可以合并为一个复合机器人。

我们把机器人用 1 至 n 编号(n ≤ 9)。如果两个机器人的编号是连续的,那 么它们是兼容的,可以合并成一个复合机器人。最初这 n 个机器人各自都只有唯 一的编号。而一个由两个或以上的机器人合并构成的复合机器人拥有两个编号, 分别是构成它的所有机器人中最小和最大的编号。

例如,2 号机器人只可以与 1 号或 3 号机器人合并。若 2 号机器人与 3 号机 器人合并,可构成编号为 2-3 的复合机器人。如果编号为 2-3 的复合机器人与编 号为 4-6 的复合机器人合并,可构成编号为 2-6 的复合机器人。当所有机器人合 并以后则构成 1-n 复合机器人。

工程师把这 n 个机器人放在了一个封闭的房间中,房间四周均是墙。该房间 被划分成 w × h 个方格。有些方格有障碍物,机器人不可经过或停留;其余方格 允许多个机器人停留,同时允许机器人经过。任何时候一个机器人只占用一个方 格。初始时刻,所有机器人均在不同的方格中。

这些原始的机器人不会自发地移动。它们只有被工程师沿 x 轴或 y 轴推动 后,才会沿推动的方向不断向前直线移动,直至碰到障碍物或墙停止移动。停止 移动后,它会扫描当前的格子是否存在可以与它合并的机器人,如果有,则合并 并继续检查,直至不能再合并为止。工程师只能沿水平向左、水平向右、竖直向 上、竖直向下四个方向推动机器人,并且,在机器人尚未停止移动时,不允许推 动其它机器人,因此任何时刻,房间中都只能有一个机器人移动。

为了帮助机器人转向,工程师在一些格子中放置了转向器。具体地说,转向 器分为顺时针转向器(右转器)和逆时针转向器(左转器),顺时针转向器可以 使到达该格子的机器人沿顺时针方向转向 90°;逆时针转向器可以使到达该格 子的机器人沿逆时针方向转向 90°。

现在,我们将告诉你初始时刻房间内的信息。请你计算工程师最少共计需要 推动机器人多少次,才能把所有的 n 个机器人全部合并(如果可能的话)。

输入输出格式

输入格式:

你的程序必须从标准输入读入。

输入的第 1 行包含 3 个整数 n、w 和 h,用 空格隔开。

输入文件中接下来的 h 行描述初始时刻房间内的信息,每行包含 w 个字符。 这 w × h 个字符中每一个表示房间中的一个格子,意义如下:

‘1’至‘9’:表示该方格中有一个机器人,编号为这个数字;

‘x’:表示该方格有障碍物;

‘A’:表示该方格中有一个逆时针转向器;

‘C’:表示该方格中有一个顺时针转向器;

‘.’:表示该方格为空地。

输出格式:

你的程序必须输出到标准输出。输出仅一个整数,表示最少需要推动的次数。 若不能使所有机器人全部合并,输出-1。

输入输出样例

输入样例#1: 复制

4 10 5
1.........
AA...x4...
..A..x....
2....x....
..C.3.A...
输出样例#1: 复制

5

说明

第一步:向右推动 3 号机器人,当它碰到转向器后会向上继续移动,直至碰 到墙壁停止移动。

第二步:向上推动 4 号机器人,当它碰到墙壁后停止移动,与 3 号机器人合 并,构成 3-4 号机器人

第三步:向上推动 2 号机器人,当它碰到转向器后会向左移动,由于左侧为 墙壁,故停留在原地。

第四步:向右推动 2 号机器人,由于它在一个转向器上,故它会向上移动, 直至碰到墙壁停止移动,与 1 号机器人合并,构成 1-2 号机器人。

第五步:向左推动 3-4 号机器人,当它碰到墙壁后停止移动,与 1-2 号机器 人合并,构成 1-4 号机器人。

我们将使用以下 4 类输入测例测试你的程序

测例满足 n ≤ 9,w ≤ 500 且 h ≤ 500。

因为每一次只能与相邻机器人合并

所以f[l][r][x][y]表示编号l~r的机器人在(x,y)合并的最小代价

预处理出d[i][x][y]表示i方向能走到哪个点

然后又两种转移:

f[l][r][x][y]=min(f[l][k][x][y]+f[k+1][r][x][y])

f[l][r][dx][dy]=min(f[l][r][x][y]+1)

第二种可以用SPFA解决

但是会超时,用单调队列也解决不了

用双端队列,第一个储存所有起始点,按f[l][r][x][y]排序

另一个队列储存到的点

每一次从两个队列中选出最小的f[l][r][x][y]进行拓展

不要用STL

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
struct ZYYS
{
int x,y,d;
}a[],q[],Q[];
char s[][];
const int dx[]={-,,,},dy[]={,-,,};
int f[][][][],inf=1e9,n,m,cnt,g[][][],tag[][][],top,vis[][],ans;
bool cmp(ZYYS a,ZYYS b)
{
return a.d<b.d;
}
int cal(int x,int y)
{
return (x-)*m+y;
}
int dfs(int k,int x,int y)
{
if (x<=||x>n||y<=||y>m) return ;
if (g[k][x][y]) return g[k][x][y];
if (s[x][y]=='x') return ;
if (tag[k][x][y]) return -;
tag[k][x][y]=;
int t=k;
if (s[x][y]=='A') k=(k+)%;
if (s[x][y]=='C') k=(k+)%;
g[t][x][y]=dfs(k,x+dx[k],y+dy[k]);
tag[t][x][y]=;
if (g[t][x][y]==) g[t][x][y]=cal(x,y);
return g[t][x][y];
}
int main()
{int i,j,k,l,r,L,R,LL,RR;
cin>>cnt>>m>>n;
for (i=;i<=n;i++)
for (j=;j<=m;j++)
for (l=;l<=cnt;l++)
for (k=;k<=cnt;k++)
f[l][k][i][j]=inf;
for (i=;i<=n;i++)
{
scanf("%s",s[i]+);
for (j=;j<=m;j++)
{
if (s[i][j]>=''&&s[i][j]<='')
k=s[i][j]-'',a[k].x=i,a[k].y=j,f[k][k][i][j]=;
}
}
for (i=;i<=n;i++)
{
for (j=;j<=m;j++)
if (s[i][j]!='x')
{
for (k=;k<;k++)
g[k][i][j]=dfs(k,i,j);
}
}
for (l=cnt;l>=;l--)
for (r=l;r<=cnt;r++)
{
for (k=l;k<r;k++)
for (i=;i<=n;i++)
for (j=;j<=m;j++)
f[l][r][i][j]=min(f[l][r][i][j],f[l][k][i][j]+f[k+][r][i][j]);
top=;
memset(vis,,sizeof(vis));
for (i=;i<=n;i++)
{
for (j=;j<=m;j++)
{
if (f[l][r][i][j]!=inf) q[++top]=(ZYYS){i,j,f[l][r][i][j]},vis[i][j]=;
}
}
sort(q+,q+top+,cmp);
L=;R=top;LL=;RR=;
while (L!=R||LL!=RR)
{//cout<<L<<' '<<R<<' '<<LL<<' '<<RR<<endl;
ZYYS u;
if (L==R||(LL!=RR&&f[l][r][q[L].x][q[L].y]>f[l][r][Q[LL].x][Q[LL].y]))
{
LL++;
if (LL>) LL-=;
u=Q[LL];
}
else
{
L++;
u=q[L];
if (L>) L-=;
}
vis[u.x][u.y]=;
for (i=;i<;i++)
{
if (g[i][u.x][u.y]==-) continue;
int x=(g[i][u.x][u.y]-)/m+,y=(g[i][u.x][u.y]-)%m+;
if (f[l][r][x][y]>f[l][r][u.x][u.y]+)
{
f[l][r][x][y]=f[l][r][u.x][u.y]+;
if (vis[x][y]==)
{
vis[x][y]=;
RR++;
if (RR>) RR-=;
Q[RR]=(ZYYS){x,y,f[l][r][x][y]};
}
}
}
}
}
ans=inf;
for (i=;i<=n;i++)
for (j=;j<=m;j++)
ans=min(ans,f[][cnt][i][j]);
if (ans==inf) cout<<-;
else
cout<<ans;
}

[APIO2013]机器人的更多相关文章

  1. bzoj3205 [Apio2013]机器人

    3205: [Apio2013]机器人 Time Limit: 15 Sec  Memory Limit: 128 MBSubmit: 953  Solved: 227[Submit][Status] ...

  2. [Bzoj3205][Apio2013]机器人(斯坦纳树)(bfs)

    3205: [Apio2013]机器人 Time Limit: 15 Sec  Memory Limit: 128 MBSubmit: 977  Solved: 230[Submit][Status] ...

  3. [APIO2013]机器人(斯坦纳树)

    题目描述 VRI(Voltron 机器人学会)的工程师建造了 n 个机器人.任意两个兼容的机 器人站在同一个格子时可以合并为一个复合机器人. 我们把机器人用 1 至 n 编号(n ≤ 9).如果两个机 ...

  4. [APIO2013]机器人[搜索、斯坦纳树]

    题意 题目链接 分析 记 g(d,x,y) 表示从 (x,y) 出发,方向为 d 到达的点,这个可以通过记忆化搜索求出,注意如果转移成环(此时向这个方向走没有意义)要特判. 记 f(l,r,x,y) ...

  5. bzoj千题计划230:bzoj3205: [Apio2013]机器人

    http://www.lydsy.com/JudgeOnline/problem.php?id=3205 历时一天,老子终于把它A了 哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈 因为不懂spfa ...

  6. BZOJ3205/UOJ107 [Apio2013]机器人

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  7. 【题解】APIO2013机器人

    其实这题前前后后的思考时间加起来应该有两天之久了,dp状态,转移方式等等都还是比较好想,然而左看右看觉得spfa复杂度未免太爆炸……然后选择看了一篇题解,发现在多重优化之下,其实是可以过的…… 首先建 ...

  8. bzoj 3205: [Apio2013]机器人【dfs+斯坦纳树+spfa】

    第一次听说斯坦纳树这种东西 先dfs预处理出来dis[i][j][k]表示格子(i,j)向k方向转移能到哪,记忆话搜索预处理,注意如果有环的话特判一下 设f[i][j][x][y]表示复合机器人i-j ...

  9. 【BZOJ3205_洛谷3638】[APIO2013]机器人(动态规划)

    题目: 洛谷3638 分析: 卡了一天的神题--(OrzJumpmelon) 首先预处理出从点\(p\)向\(d\)方向出发最终能到达的点\(nxt[p][d]\).这个可以直接记忆化搜索解决.如果出 ...

随机推荐

  1. sql limit offset 区别

    select * from table limit 2,1;                  //含义是跳过2条取1条数据,即读取第3条数据 select * from table limit 2 ...

  2. C语言 结构体(嵌套结构体--结构体数组)

    //结构体--嵌套结构体和结构体数组 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> ...

  3. Cocos2dx 场景切换动画

    1.http://www.cnblogs.com/linux-ios/archive/2013/04/09/3009292.html

  4. ASP.NET:把ashx写到类库里并在页面上调用的具体方法

    在类库中建Http Handler的操作很简单,就是添加一个普通的类,然后把之前ashx里的代码几乎一模一样贴到这个类中.但要注意命名空间和类名,因为之后我们会用 到.样例Handler: names ...

  5. git分支管理与冲突解决(转载)

    Git 分支管理和冲突解决 原文:http://www.cnblogs.com/mengdd/p/3585038.html 创建分支 git branch 没有参数,显示本地版本库中所有的本地分支名称 ...

  6. Scrapy爬虫笔记

    Scrapy是一个优秀的Python爬虫框架,可以很方便的爬取web站点的信息供我们分析和挖掘,在这记录下最近使用的一些心得. 1.安装 通过pip或者easy_install安装: 1 sudo p ...

  7. Linux文件类型及目录配置

    Linux文件类型与扩展名 在Linux系统中,任何硬件设备或者其他设备都是以文件的形式存在,就连数据通信的接口这些也是由专门的文件来负责的,因此Linux的文件种类就非常多,出了之前我们常见的 - ...

  8. 《从零开始学Swift》学习笔记(Day 33)——属性观察者

    原创文章,欢迎转载.转载请注明:关东升的博客 为了监听属性的变化,Swift提供了属性观察者.属性观察者能够监听存储属性的变化,即便变化前后的值相同,它们也能监听到. 属性观察者主要有以下两个: l ...

  9. Linux下带宽流量工具iftop实践

    在Linux/类Unix系统中可以使用top查看系统资源.进程.内存占用等信息.查看网络状态可以使用netstat.nmap等工具.若要查看实时的网络流量,监控TCP/IP连接等,则可以使用iftop ...

  10. Error: unable to connect to node rabbit@10: nodedown 修改hostname后异常

    https://blog.csdn.net/witsmakemen/article/details/22651365 [root@d bin]# rabbitmqctl start_appStarti ...