Hackerrank - [Algo] Matrix Rotation
https://www.hackerrank.com/challenges/matrix-rotation-algo
又是一道耗了两小时以上的题,做完了才想起来,这不就是几年前在POJ上做过的一个同类问题么:置换群问题。
给定义一个MxN的矩阵,让你按照从外到内一圈圈地,逆时针旋转R次。如果你打算一次次地转,那就掉坑里了,因为这题的暴力算法比高效算法还难写对。
这其实是置换的一个特例,比如给你一个排列[2, 4, 1, 3],让你按照这个对应关系把长度为4的数组变换R次,问最后的结果。
想到了什么吗?当然是矩阵的快速幂啦!什么矩阵?一个01稀疏矩阵。
[2, 4, 1, 3]可以表示为:
[0 1 0 0]
[0 0 0 1]
[1 0 0 0]
[0 0 1 0]
联系大一学的线性代数知识,这就是这个置换操作对应的左乘变换啊(线性变换)。
把[a, b, c, d]通过一次变换变成了[b, d, a, c]。那么变一亿次之后是什么呢?实际上置换是有循环节的,不过无所谓,有快速幂就不用操心循环节了。
于是变换R次也就是把这矩阵求R次幂,于是快速幂算法就派上用场了。
这题也是类似,只不过构造这个变换矩阵麻烦点,你要看矩阵旋转一次是怎么对应的。得出矩阵以后,求幂就容易了。
时间O(N * M * log(R)),空间一样。
import re def get2DMatrix(n, m, val):
return [[val for j in xrange(m)] for i in xrange(n)] def rotate(a, r):
# n is guaranteed to be even
n = len(a)
m = len(a[0])
s = getDisplace(n, m)
s = displacePow(s, r)
b = get2DMatrix(n, m, 0)
for i in xrange(n):
for j in xrange(m):
b[i][j] = a[s[i * m + j] / m][s[i * m + j] % m]
return b def getDisplace(n, m):
s = range(n * m)
i = 0
while i < n / 2 and i < m / 2:
rr = n - 2 * i
cc = m - 2 * i
for j in xrange(1, rr, 1):
#left
s[(j + i) * m + i] = (j - 1 + i) * m + i
for j in xrange(1, cc, 1):
#down
s[(rr - 1 + i) * m + (j + i)] = (rr - 1 + i) * m + (j - 1 + i)
for j in xrange(rr - 2, -1, -1):
#right
s[(j + i) * m + (cc - 1 + i)] = (j + 1 + i) * m + (cc - 1 + i)
for j in xrange(cc - 2, -1, -1):
#top
s[i * m + (j + i)] = i * m + (j + 1 + i)
i += 1
return s def multiply(a, b):
n = len(a)
c = []
for i in xrange(n):
c.append(a[b[i]])
return c def displacePow(a, k):
if k == 1:
return a[:]
a2 = displacePow(a, k >> 1)
if k & 1:
return multiply(multiply(a2, a2), a)
else:
return multiply(a2, a2) if __name__ == '__main__':
n, m, r = map(int, re.split('\s+', raw_input().strip()))
a = []
for i in xrange(n):
a.append(map(int, re.split('\s+', raw_input().strip())))
a = rotate(a, r)
for i in xrange(n):
print(' '.join(map(str, a[i])))
Hackerrank - [Algo] Matrix Rotation的更多相关文章
- Hackerrank - Game Of Rotation 题解
旋转一个数组以得到最大值. 陷阱就是:不能排序.须要模拟操作旋转,并设计公式计算旋转后的和. 要求是O(n)时间完毕. 原题: https://www.hackerrank.com/challenge ...
- 主成分分析(PCA)原理及R语言实现
原理: 主成分分析 - stanford 主成分分析法 - 智库 主成分分析(Principal Component Analysis)原理 主成分分析及R语言案例 - 文库 主成分分析法的原理应用及 ...
- 【Unity Shaders】学习笔记——SurfaceShader(十一)光照模型
[Unity Shaders]学习笔记——SurfaceShader(十一)光照模型 转载请注明出处:http://www.cnblogs.com/-867259206/p/5664792.html ...
- 【Unity Shaders】法线纹理(Normal Mapping)的实现细节
写在前面 写这篇的目的是为了总结我长期以来的混乱.虽然题目是"法线纹理的实现细节",但其实我想讲的是如何在shader中编程正确使用法线进行光照计算.这里面最让人头大的就是各种矩阵 ...
- 主成分分析(PCA)原理及R语言实现 | dimension reduction降维
如果你的职业定位是数据分析师/计算生物学家,那么不懂PCA.t-SNE的原理就说不过去了吧.跑通软件没什么了不起的,网上那么多教程,copy一下就会.关键是要懂其数学原理,理解算法的假设,适合解决什么 ...
- Must practice programming questions in all languages
To master any programming languages, you need to definitely solve/practice the below-listed problems ...
- Unity Shader-法线贴图(Normal)及其原理
简介 以前经常听说“模型不好看啊,怎么办啊?”答曰“加法线”,”做了个高模,准备烘一下法线贴图”,“有的美术特别屌,直接画法线贴图”.....法线贴图到底是个什么鬼,当年天真的我真的被这个图形学的奇淫 ...
- 相机imu外参标定
1. 第一步初始化imu外参(可以从参数文档中读取,也可以计算出),VINS中处理如下: # Extrinsic parameter between IMU and Camera. estimate_ ...
- VINS(二)Feature Detection and Tracking
系统入口是feature_tracker_node.cpp文件中的main函数 1. 首先创建feature_tracker节点,从配置文件中读取信息(parameters.cpp),包括: ROS中 ...
随机推荐
- python:类的基本特征------继承、多态与封装
一.继承 1,什么是继承 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类 python中类的继承分为:单继承和多继承 cl ...
- Uva 11600 期望DP
题意:n个城市,相互可达(有n(n-1)/2条边),其中有一些道路上面有妖怪,现在,从1号城市出发,随机挑取一个城市走去,这个道路上的妖怪就会被消灭,求: 在平均情况下,需要走多少步,使得任意两个城市 ...
- 动态规划(DP),最长递增子序列(LIS)
题目链接:http://poj.org/problem?id=2533 解题报告: 状态转移方程: dp[i]表示以a[i]为结尾的LIS长度 状态转移方程: dp[0]=1; dp[i]=max(d ...
- 2018.11.15 Nginx服务器的使用
Nginx简单教程 1.什么是Nginx? Nginx(engine x)是一款轻量级的Web服务器.反向代理服务器及电子邮件(IMAP/POP3)代理服务器 什么是反向代理服务器? 反向代理方式是指 ...
- 如何在vue2.0项目中引用element-ui和echart.js
1 项目中怎样添加elment-ui 和 echart.js 1.1直接在packjson 里面的 dependencies 配置 "element-ui": "^1.3 ...
- CentOS6.6上进程挂起的诡异问题和处理
由于新的服务器不再支持CentOS5.4系统了,我们在新装机器上安装CentOS6.6.随着CentOS6.6机器的增多,我们逐渐注意到一个诡异问题:运行在这些机器上的某些进程,容易莫名其妙地挂起(举 ...
- 数字图像处理学习笔记之一 DIP绪论与MATLAB基础
写在前面的话 数字图像处理系列的学习笔记是作者结合上海大学计算机学院<数字图像处理>课程的学习所做的笔记,使用参考书籍为<冈萨雷斯数字图像处理(第二版)(MATLAB版)>,同 ...
- javascript跳转页面
<script type="text/javascript"> function openNewTab() { parent.addExampleTab({ id: a ...
- C#中rpt的数据类型和Oracle中数据类型的匹配
Oracle中number数据类型对应C#中decimal数据类型,结果是整数 Oracle中number数据类型对应C#中int32数据类型,结果是小数,保留两位小数 Oracle中中date类型数 ...
- 你不知道的javaScript笔记(4)
类型: JavaScript 有7种内置类型 空值 (null) 未定义(undefined) 布尔值(boolean) 数字(number) 字符串(string) 对象(object) 符号(sy ...