Gym101845L.L-shapes

棋盘填充问题解析
本文介绍了一个关于棋盘填充的问题,需要使用特定的L形瓷砖和一个1x1的方块来填充一个N×N的棋盘,其中一个1x1的方块已放置于特定位置。文章提供了一种通过递归四分法来解决该问题的方法,并给出了详细的代码实现。

http://codeforces.com/group/NVaJtLaLjS/contest/241861/problem/L
The Che square of the Universidad Nacional de Colombia is represented by an N × N matrix and is going to be remodeled. To achieve this goal, the engineers have one 1 × 1 square-tile and a lot of L-tiles (Enough to fill the entire Che square). Unfortunately, one of the workers have placed the square tile at location in row R and column C ignoring the fact that this could affect the positions of other tiles. Given the importance of the Che square, we need your help in order to know how to place the rest of the tiles so that all N2 positions of the Che square are covered by exactly tile.

The rotations of a L-tile are showed at the following figure, you can place each L-tile in the rotation you want.
在这里插入图片描述

Input
The first line contains N (1 ≤ N ≤ 2048, will be a power of 2), the size of the square matrix. The second line contains integers R and C (1 ≤ R, C ≤ N), the row and the column where the worker placed the square tile.

Output
Print a matrix of size N × N ]. The C-th character of the R-th line must be a dot (’.’), representing the 1 × 1 square tile. Every L-tiles must be represented by three uppercase letters. If two L-tiles are adjacent to each other (share more than a point), they must be represented by different letters. Since there are many possible answers, you can print any.

Example
inputCopy
8
3 4
outputCopy
BBCCBBCC
BAACBAAC
CAB.CCAB
CCBBACBB
BBCAABCC
BACCBBAC
CAABCAAB
CCBBCCBB

题意:有一个n*n的矩阵(n是2的幂次),含有1个‘.’,要求用给定的四种格子拼满所有的空缺。
思路:
有一个性质:将矩阵分成四份(左上,左下,右上,右下),则含有’.‘的那一块可以拼满,其余三块都拼不满,会空出来一个小格子。
我们对这个矩阵进行递归四分,对于不含’.‘的三块,在交界处直接放上3个相同字符(这样就转化为了假定那里放了’.’,于是四个小矩阵都可以拼满)。
设计dfs(x,y,l,p):左上角坐标第x行,第y列,边长为l,这个矩阵的左上/右上/左下/右下已经被填标记为1,2,3,4。

#include<bits/stdc++.h>
using namespace std;
#define maxn 2050

int n,r,c;
int a[maxn][maxn];

bool inside(int x,int y,int l){return r>=x&&r<=x+l-1&&c>=y&&c<=y+l-1;}

void dfs(int x,int y,int l,int p)
{
    if(l==2)
    {
        if(inside(x,y,l))
        {
            if(x!=r||y!=c)a[x][y]=p;
            if(x+1!=r||y!=c)a[x+1][y]=p;
            if(x!=r||y+1!=c)a[x][y+1]=p;
            if(x+1!=r||y+1!=c)a[x+1][y+1]=p;
        }
        else
        {
            if(p==1)a[x+1][y]=a[x][y+1]=a[x+1][y+1]=p;
            else if(p==2)a[x+1][y]=a[x][y]=a[x+1][y+1]=p;
            else if(p==3)a[x][y]=a[x][y+1]=a[x+1][y+1]=p;
            else if(p==4)a[x+1][y]=a[x][y+1]=a[x][y]=p;
        }
        return;
    }
    if(inside(x,y,l/2)||inside(x+l/2,y,l/2)||inside(x,y+l/2,l/2)||inside(x+l/2,y+l/2,l/2))
    {
        if(!inside(x,y,l/2))a[x+l/2-1][y+l/2-1]=5,dfs(x,y,l/2,4);
        else dfs(x,y,l/2,0);
        if(!inside(x+l/2,y,l/2))a[x+l/2][y+l/2-1]=5,dfs(x+l/2,y,l/2,2);
        else dfs(x+l/2,y,l/2,0);
        if(!inside(x,y+l/2,l/2))a[x+l/2-1][y+l/2]=5,dfs(x,y+l/2,l/2,3);
        else dfs(x,y+l/2,l/2,0);
        if(!inside(x+l/2,y+l/2,l/2))a[x+l/2][y+l/2]=5,dfs(x+l/2,y+l/2,l/2,1);
        else dfs(x+l/2,y+l/2,l/2,0);
    }
    else 
    {
        if(p==1)
        {
            a[x+l/2][y+l/2]=5;
            a[x+l/2][y+l/2-1]=5;
            a[x+l/2-1][y+l/2]=5;
            dfs(x,y,l/2,1);
            dfs(x,y+l/2,l/2,3);
            dfs(x+l/2,y,l/2,2);
            dfs(x+l/2,y+l/2,l/2,1);
        }
        else if(p==2)
        {
            a[x+l/2-1][y+l/2-1]=5;
            a[x+l/2][y+l/2]=5;
            a[x+l/2][y+l/2-1]=5;
            dfs(x,y,l/2,4);
            dfs(x,y+l/2,l/2,2);
            dfs(x+l/2,y,l/2,2);
            dfs(x+l/2,y+l/2,l/2,1);           
        }
        else if(p==3)
        {
            a[x+l/2-1][y+l/2-1]=5;
            a[x+l/2][y+l/2]=5;
            a[x+l/2-1][y+l/2]=5;
            dfs(x,y,l/2,4);
            dfs(x,y+l/2,l/2,3);
            dfs(x+l/2,y,l/2,3);
            dfs(x+l/2,y+l/2,l/2,1);
        }
        else if(p==4)
        {
            a[x+l/2-1][y+l/2-1]=5;
            a[x+l/2][y+l/2-1]=5;
            a[x+l/2-1][y+l/2]=5;
            dfs(x,y,l/2,4);
            dfs(x,y+l/2,l/2,3);
            dfs(x+l/2,y,l/2,2);
            dfs(x+l/2,y+l/2,l/2,4);
        }
    }
}

int main()
{
    //freopen("input.in","r",stdin);
    //freopen("output.out","w",stdout);
    cin>>n>>r>>c;
    if(n==1){cout<<"."<<endl;exit(0);}
    dfs(1,1,n,0);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(r==i&&j==c)putchar('.');
            else putchar('A'+a[i][j]);
        }
        putchar('\n');
    }
    return 0;
}
<think>根据用户提供的代码片段,他们正在尝试使用类似"PongNoFrameskip-v4"这样的环境名称,但在新版的Gym中这些环境已经被移除。因此,需要将代码迁移到新版Gym的ALE环境。解决方案:1.将环境名称改为新的ALE命名方式,例如"ALE/Pong-v5"等。2.注意,新版ALE环境默认不包含帧跳过(frame skipping)和帧堆叠(frame stacking),需要手动添加这些包装器(wrappers)来模拟旧版行为。3.如果用户有自定义的AtariWrapper,可能需要调整以适应新版环境。具体修改建议如下:原代码:ifargs.env_name =="pong":env= gym.make("PongNoFrameskip-v4")elif args.env_name== "breakout":env =gym.make("BreakoutNoFrameskip-v4")else:env =gym.make("BoxingNoFrameskip-v4")env= AtariWrapper(env)修改为:#首先,将环境名称映射到新的ALE名称env_id= {"pong": "ALE/Pong-v5","breakout": "ALE/Breakout-v5","boxing": "ALE/Boxing-v5"#注意:原代码中else分支是Boxing,这里使用小写匹配}.get(args.env_name, "ALE/Pong-v5")#默认使用Pong#创建基础环境env= gym.make(env_id, render_mode="rgb_array")#如果需要渲染,指定render_mode#然后应用帧跳过和帧堆叠等包装器#假设原来的AtariWrapper实现了帧跳过、帧堆叠和预处理等功能,我们可以用Gym提供的标准包装器替代#如果没有,则可以使用以下标准包装器:#每4帧执行一次动作,并返回中间帧的最大值(这是Atari的常见设置)env =gym.wrappers.AtariPreprocessing(env, frame_skip=4, grayscale_obs=True, scale_obs=True)#如果需要帧堆叠,可以再添加FrameStack包装器,通常堆叠4帧env =gym.wrappers.FrameStack(env,num_stack=4)注意:如果用户原来的AtariWrapper有特殊处理,可能需要调整。这里假设使用Gym自带的AtariPreprocessing和FrameStack。另外,需要确保安装了必要的包:pip installale-pygym[atari,accept-rom-license]如果用户需要保持与旧版相同的预处理,可以查看AtariPreprocessing的文档:https://www.gymlibrary.dev/api/wrappers/#ataripreprocessing但是,请注意,AtariPreprocessing默认会将图像转换为灰度,并且缩放为84x84。如果用户原来的AtariWrapper有不同的处理,需要相应调整参数。如果用户不想改变预处理方式,也可以自己实现包装器,但建议使用官方提供的包装器以确保兼容性。最后,由于环境名称的改变,用户需要将args.env_name与新的环境名称映射好。这里我假设用户传入的args.env_name是字符串"pong"、"breakout"或"boxing"(小写),如果原代码中传入的是大写,则需要调整映射字典。如果用户的环境名称参数是其他值,需要根据实际情况修改映射。因此,修改后的代码示例: ```python#导入必要的包装器importgymfrom gym.wrappers importAtariPreprocessing, FrameStack#环境名称映射字典env_map= {"pong": "ALE/Pong-v5","breakout": "ALE/Breakout-v5","boxing": "ALE/Boxing-v5" }#获取新环境名称,如果args.env_name不在字典中,则使用默认(例如Pong)env_id= env_map.get(args.env_name,"ALE/Pong-v5") #创建环境env =gym.make(env_id,render_mode="rgb_array")#如果需要渲染,可以指定render_mode#应用预处理:帧跳过4,灰度化,缩放为84x84env =AtariPreprocessing(env, frame_skip=4, grayscale_obs=True, scale_obs=True)#帧堆叠4帧env =FrameStack(env, num_stack=4)#注意:如果用户需要其他预处理参数(如不进行缩放,或者不同的帧跳过等),可以调整AtariPreprocessing的参数```注意:在Gym0.26及以上版本中,创建环境时需要指定render_mode(如果需要渲染的话)。在训练时可能不需要渲染,但在测试或展示时可能需要。这里指定为"rgb_array"以便后续如果需要获取图像。另外,如果用户代码中原来有`env =AtariWrapper(env)`,那么现在应该移除,因为我们已经用标准包装器替代了。如果用户原来的AtariWrapper有其他功能(比如奖励裁剪、结束条件等),则需要额外添加相应的包装器。以上修改应该能解决环境名称不存在的问题,并确保环境具有与旧版类似的帧跳过和预处理功能。 §§相关问题§§1.如何在新版Gym中自定义Atari环境的帧跳过(frame skipping)参数? 2.使用FrameStack包装器时如何确保观测空间的正确维度? 3.如果不想使用灰度图像,如何设置AtariPreprocessing包装器? 4.如何在新版Atari环境中获取游戏状态(如剩余生命值)以进行生命结束条件判断? 5.在迁移旧版Atari代码时,如何处理新版Gym环境返回的info字典结构变化?</think>根据您提供的代码片段,您正在尝试使用旧版Atari环境名称(如`PongNoFrameskip-v4`),这些名称在Gym 0.26+版本中已被弃用。以下是完整的解决方案: ### 代码修复方案 ```python import gym from gym.wrappers import FrameSkip, FrameStack, ResizeObservation, GrayScaleObservation # 环境名称映射表(旧名称 → 新名称) ENV_MAP = { "pong": "ALE/Pong-v5", "breakout": "ALE/Breakout-v5", "boxing": "ALE/Boxing-v5" } # 获取新版环境名称 env_id = ENV_MAP.get(args.env_name, "ALE/Pong-v5") # 默认使用Pong # 创建基础环境 env = gym.make( env_id, render_mode="rgb_array", # 渲染模式 obs_type="rgb", # 观测类型(rgb/gray/ram) full_action_space=False # 使用简化动作空间 ) # 应用必要的包装器(模拟旧版行为) env = FrameSkip(env, skip=4) # 帧跳过(每4帧执行一次动作) env = ResizeObservation(env, (84, 84)) # 调整观测尺寸 env = GrayScaleObservation(env) # 灰度化 env = FrameStack(env, 4) # 帧堆叠(堆叠最后4帧) # 替换您原有的AtariWrapper # env = AtariWrapper(env) # 删除或修改此包装器 ``` ### 关键修改说明: 1. **环境名称映射**: - 使用新版ALE前缀环境(`ALE/GameName-v5`) - 创建映射表处理不同游戏名称 2. **帧跳过与堆叠**: - `FrameSkip`包装器实现动作重复 - `FrameStack`包装器实现帧堆叠 - 参数`skip=4`和`stack_size=4`模拟旧版`NoFrameskip`行为 3. **观测预处理**: - `ResizeObservation`调整观测尺寸 - `GrayScaleObservation`转换为灰度图像 - 替代您原有的`AtariWrapper` 4. **环境配置**: - `render_mode="rgb_array"` 获取图像数据 - `full_action_space=False` 使用简化动作空间(18个动作) - `obs_type="rgb"` 获取RGB图像观测 ### 依赖安装: ```bash pip install "gym[atari,accept-rom-license]" ale-py ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值