P11864 「o.OI R1」α+β Problem

题目背景

机器人小 α\alphaα 喜欢做游戏,机器人小 β\betaβ 喜欢玩游戏。

题目描述

现在,它们正在玩一个叫作推箱子的游戏!

机器人小 β\betaβ 为关卡制定了一个用字符串表示的移动路径:

字符含义
W让机器人前进一格
S让机器人后退一格
A让机器人左转
D让机器人右转

身为机器人小 α\alphaα,你需要构造一个 n×mn\times mn×m 的地图:

字符含义
|机器人无法穿过的墙壁
X机器人最开始在的位置
S箱子最开始所在的位置
.空地

注意每个位置的东西只能是以上四种之一。

机器人的初始位置是给定的,方向朝上,地图外都是墙。

小 β\betaβ 完成移动后,所有箱子都必须移动过,小 α\alphaα 需要让这个地图的箱子数最多,且小 β\betaβ 每步操作都合法。

以下给出所有不合法的操作:

操作不合法情况
W机器人前方是墙
W机器人前方两格都是箱子
W机器人前方两格分别是箱子和墙
S机器人后方是箱子或墙

小 α\alphaα 需要一份程序来完成这份工作。

输入格式

本题有多组数据。

第一行一个正整数 TTT 表示数据组数。

对于每组数据:

  • 第一行两个整数 n,mn,mn,m。
  • 第二行三个整数 x,y,kx,y,kx,y,k。
  • 第三行一个长度为 kkk 的字符串 sss。

输入的数据含义如下:

  • nnn 和 mmm 代表需要构造的地图的大小为 nnn 行 mmm 列。
  • xxx 和 yyy 代表机器人的初始位置在从上往下第 xxx 行从左往右第 yyy 列。
  • kkk 代表移动路径的长度,sss 代表移动路径。

本题数据量较大,请使用较快的读写方式。

输出格式

对于每组数据,你需要给出一个 n×mn\times mn×m 的地图代表你构造的地图,格式如题目描述所述。

所有最优的答案都可以得分。

输入输出样例 #1

输入 #1

1
3 4
2 2 17
DWSAWDWSSDWAWDWAW

输出 #1

..S.
SXS.
..S.

输入输出样例 #2

输入 #2

1
3 4
3 4 9
WSAWWDWDW

输出 #2

|.|.
|SSS
..SX

输入输出样例 #3

输入 #3

1
3 4
2 1 8
DWASDWAW

输出 #3

||.|
XS.|
|.S.

输入输出样例 #4

输入 #4

2
5 4
5 1 9
WDWAWDWAW
5 19
5 8 12
DDSAADDADADW

输出 #4

....
..S.
.SS.
SS..
X...
.........||||||||||
.........||......||
||||||...||......||
||..||...||......||
||||||.X.||||||||||

说明/提示

部分样例有其他正确答案。

「数据范围」

本题开启 Special Judge 与捆绑测试。

一个测试点内,如果对于每组数据你的箱子数是最多的,且方案合法,你才能获得该测试点的分数。

只有通过一个子任务内的所有测试点才能得到该子任务的分数。

对于所有测试数据,保证:

  • 1≤n,m≤20001\leq n,m\leq 20001≤n,m≤2000,1≤∑nm≤4×1061\leq \sum nm\leq 4\times 10^61≤∑nm≤4×106。
  • 1≤x≤n1\leq x\leq n1≤x≤n,1≤y≤m1\leq y\leq m1≤y≤m。
  • 1≤k,∑k≤1061\leq k,\sum k\leq 10^61≤k,∑k≤106。
  • si∈{W,A,S,D}s_i\in\{\texttt{W},\texttt{A},\texttt{S},\texttt{D}\}si​∈{W,A,S,D}。
  • 小 β\betaβ 的移动在空旷地图下一定合法。
子任务n,mn,mn,m∑nm\sum nm∑nm∑k\sum k∑k特殊性质分值
000≤4\leq4≤4≤40\leq 40≤40≤100\leq100≤100无101010
111=45=45=45=2025=2025=2025≤103\leq10^3≤103A101010
222≤200\leq200≤200≤4×104\leq 4\times 10^4≤4×104≤103\leq10^3≤103无202020
333≤1000\leq1000≤1000≤2×106\leq 2\times 10^6≤2×106≤106\leq10^6≤106B151515
444≤1000\leq1000≤1000≤2×106\leq 2\times 10^6≤2×106≤106\leq10^6≤106C202020
555≤2000\leq2000≤2000≤4×106\leq 4\times 10^6≤4×106≤106\leq10^6≤106无252525
  • 特殊性质 A:前进和后退的总次数不超过 202020 次,且 x=y=23x=y=23x=y=23。
  • 特殊性质 B:si∈{W,A,D}s_i\in\{\texttt{W},\texttt{A},\texttt{D}\}si​∈{W,A,D},且只会朝两个方向前进。
  • 特殊性质 C:可放箱子的最大数量为 000 或 111。

尽管比赛中不会返回,我们仍将告诉你 Special Judge 会返回的对应信息,优先级递减。

  • Error: 1:出现规定以外的字符。
  • Error: 2:出生点不在正确的位置。
  • Error: 3:机器人无法前进。
  • Error: 4:机器人无法后退。
  • Error: 5:有箱子没有被推动过。
  • Error: 6:箱子数不是最多的。
  • Correct:测试点通过。

C++实现

#include <bits/stdc++.h>
using namespace std;
const int N=2003,K=1e6+6;
int t,n,m,sx,sy,k,g[N][N];
int d[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
bool val[N*N],del[N*N];
char s[K];
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d%d%d%s",&n,&m,&sx,&sy,&k,s+1);
        for(int i=1,cnt=0;i<=n;i++)
            for(int j=1;j<=m;j++)
                g[i][j]=++cnt,val[g[i][j]]=del[g[i][j]]=0;
        int x=sx,y=sy,p=0;//x,y存机器人现在的坐标,p存方向
        del[g[x][y]]=1,g[x][y]=0;//删除起点上的箱子
        for(int i=1;i<=k;i++){
            if(s[i]=='A')
                p=(p+3)%4;//左转
            else if(s[i]=='D')
                p=(p+1)%4;
            else if(s[i]=='W'){
                int xx=x+d[p][0],yy=y+d[p][1];
                if(g[xx][yy]){
                    int xxx=xx+d[p][0],yyy=yy+d[p][1];
                    if(0<xxx && xxx<=n && 0<yyy && yyy<=m)
                        del[g[xxx][yyy]]=1,g[xxx][yyy]=g[xx][yy],val[g[xx][yy]]=1;
                    else
                        del[g[xx][yy]]=1;
                    g[xx][yy]=0;
                }
                x=xx,y=yy;
            }else if(s[i]=='S'){
                int xx=x+d[(p+2)%4][0],yy=y+d[(p+2)%4][1];
                if(g[xx][yy])
                    del[g[xx][yy]]=1,g[xx][yy]=0;
                x=xx,y=yy;
                //后退,有箱子删
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(i==sx && j==sy)
                    printf("X");//起点要特判
                else
                    printf("%c",val[(i-1)*m+j] && !del[(i-1)*m+j]? 'S':'.');
            }
            puts(""); 
        }
    }
    return 0;
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐