AtCoder Regular Contest 153

《B - Grid Rotations》

思维

这道题的题意是:给定一个n行m列的二维数组,

,有Q次操作:每次操作给定(a,b),这个(a,b)将矩阵分成四部分

 

 

 

 

然后将四部分别顺时针旋转180度

求经过Q次操作后的矩阵

 

 

 

 

  

  每次给定这样的数据范围:

   

 

 

       我们处理的时候可以在等输入完n,m后

       用vector<vector<char>>a(n,vector<char>m),这样进行初始化

 

 这道题也可以用vector<string>a(n)来读入

 

  看到数据范围,如果每次Q都暴力模拟的话一定会超时

 

    我们发现:

   1.行的变化只与行本身所在位置有关,列也相同

      这个说明:我们可以将行与列的变化分开考虑,到达降纬的效果

   2.对于行来说,如:

     0 1 2 3 4 

          如果a==3, 那么变化之后行变成: 2 1 0 4 3

     发现对于行变化,就是将 下标 [0,a-1],[a,n-1]的数进行翻转

    对于列来说也是同理

 

到这里一个解决方案已经出来了:

  一般我们用vector,还是自己写的数组,进行翻转都是O(len)的时间复杂度

  

  然而如果知道 __gnu_cxx::rope STL中的可持久化数组

  

 

   其操作的时间复杂度为O(loglen),就可以在每次Q时,花上log(n)的时间就可以成功翻转

  对行来说如此,对于列来说也是如此

 

如果不知道,还有方法:

  比如说行 : 0 1 2 3 4 

  你是不是觉得 如果其去翻转,会得到很多很多种序列?

  其实也就只有 10种 ,即2*n种,n为这个序列的长度

  如何得来?

    将序列看成环,即 0与4是相邻的

    我们知道将一个序列分成两部分,然后这两部分分别进行翻转,原来相邻的数,依然相邻

    

 

 知道了这些,

  我们可以把环化成序列 如: 0 1 2 3 4 0 1 2 3 4

  可以进行顺逆时钟读取(从左往右读 或 从右往左读)n个,得到变化后的序列

  然鹅我代码会写超时。。。ORZ

  这道题我也算还没完全解决

 

posted @ 2023-01-15 16:58  次林梦叶  阅读(71)  评论(0)    收藏  举报