T292114 [传智杯 #5 练习赛] 清洁工

题目描述

有一个 n\times nn×n 的地块,一个连续 ii 分钟没人经过的地面在第 ii 分钟会落上 ii 个单位的灰,有人经过时不会落灰但灰也不会清零,在人走后第一分钟又会落上一个单位的灰,以此类推。你在这个 n\times nn×n 的范围内移动,你的移动轨迹可以描述为一个由 \text{N,S,W,E}N,S,W,E 组成的字符串,每个字母分别表示上、下、左、右。这个人一开始在点 (x,y)(x,y),每一分钟移动一步。

求最后每一个位置上落下的灰的量。

本题中的上和右分别表示 yy 轴正方向和 xx 轴正方向。保证你没有超过移动的范围。

输入格式

第一行四个正整数 n,m,x,yn,m,x,y,含义如题面所示,其中 x,yx,y 表示横纵坐标,不是数组下标。
第二行一个长度为 mm 的字符串,表示你的移动序列。

输出格式

nn 行,每行 nn 个数,第 ii 行的第 jj 个数表示坐标 (j,n-i+1)(j,ni+1) 上的灰的数量

说明/提示

本题 y 轴朝上,x 轴朝右,样例输出中的左下角表示 (1,1)(1,1),第一分钟你在初始点处,第二分钟移动到相应的位置,第 m+1m+1 分钟移动到最后一个点,但是总共只有 mm 分钟,因此最后一个点不受移动的影响


样例 1 解释:

你的移动路径为 (1,1)→(1,3)(1,1)(1,2)(2,2)(2,3)(1,3),共 44 分钟。

对于第 11 分钟,(1,1)(1,1) 灰层数不变,其余点被落下了 11 层灰。

对于第 22 分钟,(1,2)(1,2) 灰层数不变,(1,1)(1,1) 被落下了 11 层灰,其余点落下 22 层灰。

对于第 33 分钟,(2,2)(2,2) 灰层数不变,(1,1)(1,1) 落下 22 层灰,(1,2)(1,2) 落下 11 层灰,其余点落下 33 层灰。

对于第 44 分钟,(2,3)(2,3) 灰层数不变,(1,1)(1,1) 落下 33 层灰,(1,2)(1,2) 落下 22 层灰,(2,2)(2,2) 落下 11 层灰,其余点落下 44 层灰。

注意最后你移动到了 (1,3)(1,3),但是时间只有 44 分钟,所以实际上不会对 (1,3)(1,3) 造成影响。初始点不一定在 (1,1)(1,1)。

1n50,1m1000。

解题思路:参考(6条消息) T292114 [传智杯 #5 练习赛] 清洁工_上官灵晖0622的博客-CSDN博客

其实就是分开考虑,考虑一个mat数组用来记录灰尘总数,dust数组记录下一个时间灰尘落下的数量;

但是上面的题解没有解释清洁工的位置是怎么来的,我在补题的时候用了从1到n的数组,然后一直wrong,思考了下,补一下清洁工位置来的思路

 

,刚开始只写了题里面的(1,1)这个点,然后推出xi=y;(没有深入思考,我好蠢)观察以上两个点,我们发现给的x,y和真实清洁工的位置满足以下等式

xi+y=n+1;yi=xi;即推出 xi=n+1-y;剩下的步骤跟csdn上面的大佬一样,最后附上我补题的代码

  1. #include <iostream>  
  2. using namespace std;  
  3. const int N=60;  
  4. int dust[N][N];//下一时刻灰尘将落下的数量              
  5. int mat[N][N];//灰尘的总数量   
  6. char go[1010];  
  7. //mat=dust+mat;   
  8. //输入位置为x,y  
  9. //清洁工真实位置为n,y;  
  10. void mat_upgrade(int n){  
  11.     for(int i=1;i<=n;i++){  
  12.         for(int j=1;j<=n;j++){  
  13.             mat[i][j]+=dust[i][j];  
  14.         }  
  15.     }  
  16. }  
  17. void dust_upgrade(int n,int xi,int yi){  
  18.     for(int i=1;i<=n;i++){  
  19.         for(int j=1;j<=n;j++){  
  20.             dust[i][j]++;  
  21.         }  
  22.     }  
  23.     dust[xi][yi]=0;  
  24. }  
  25. int main()  
  26. {  
  27.     int n,m,x,y;//n*n面积   
  28.     int xi,yi;  
  29.     cin>>n>>m>>x>>y;  
  30.     xi=n+1-y;  
  31.     yi=x;  
  32.     for(int i=0;i<m;i++){  
  33.         cin>>go[i];  
  34.     }  
  35.     for(int i=1;i<=n;i++){  
  36.         for(int j=1;j<=n;j++){  
  37.             mat[i][j]=0;  
  38.             dust[i][j]=1;  
  39.         }  
  40.     }   
  41.     dust[xi][yi]=0;  
  42.     for(int i=0;i<m;i++){  
  43.         if(go[i]=='N')xi--;  
  44.         if(go[i]=='S')xi++;  
  45.         if(go[i]=='W')yi--;  
  46.         if(go[i]=='E')yi++;  
  47.         mat_upgrade(n);  
  48.         dust_upgrade(n,xi,yi);  
  49.     }  
  50.     for(int i=1;i<=n;i++){  
  51.         for(int j=1;j<=n;j++){  
  52.             cout<<mat[i][j]<<" ";  
  53.         }  
  54.         cout<<endl;  
  55.     }  
  56.     return 0;  
  57.  }   
posted @   SaulGoodman1  阅读(40)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示