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
这道题我也算还没完全解决

浙公网安备 33010602011771号