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的更多相关文章

  1. Hackerrank - Game Of Rotation 题解

    旋转一个数组以得到最大值. 陷阱就是:不能排序.须要模拟操作旋转,并设计公式计算旋转后的和. 要求是O(n)时间完毕. 原题: https://www.hackerrank.com/challenge ...

  2. 主成分分析(PCA)原理及R语言实现

    原理: 主成分分析 - stanford 主成分分析法 - 智库 主成分分析(Principal Component Analysis)原理 主成分分析及R语言案例 - 文库 主成分分析法的原理应用及 ...

  3. 【Unity Shaders】学习笔记——SurfaceShader(十一)光照模型

    [Unity Shaders]学习笔记——SurfaceShader(十一)光照模型 转载请注明出处:http://www.cnblogs.com/-867259206/p/5664792.html ...

  4. 【Unity Shaders】法线纹理(Normal Mapping)的实现细节

    写在前面 写这篇的目的是为了总结我长期以来的混乱.虽然题目是"法线纹理的实现细节",但其实我想讲的是如何在shader中编程正确使用法线进行光照计算.这里面最让人头大的就是各种矩阵 ...

  5. 主成分分析(PCA)原理及R语言实现 | dimension reduction降维

    如果你的职业定位是数据分析师/计算生物学家,那么不懂PCA.t-SNE的原理就说不过去了吧.跑通软件没什么了不起的,网上那么多教程,copy一下就会.关键是要懂其数学原理,理解算法的假设,适合解决什么 ...

  6. Must practice programming questions in all languages

    To master any programming languages, you need to definitely solve/practice the below-listed problems ...

  7. Unity Shader-法线贴图(Normal)及其原理

    简介 以前经常听说“模型不好看啊,怎么办啊?”答曰“加法线”,”做了个高模,准备烘一下法线贴图”,“有的美术特别屌,直接画法线贴图”.....法线贴图到底是个什么鬼,当年天真的我真的被这个图形学的奇淫 ...

  8. 相机imu外参标定

    1. 第一步初始化imu外参(可以从参数文档中读取,也可以计算出),VINS中处理如下: # Extrinsic parameter between IMU and Camera. estimate_ ...

  9. VINS(二)Feature Detection and Tracking

    系统入口是feature_tracker_node.cpp文件中的main函数 1. 首先创建feature_tracker节点,从配置文件中读取信息(parameters.cpp),包括: ROS中 ...

随机推荐

  1. pthread_create & pthread_exit

    http://www.cppblog.com/saha/articles/189802.html 1.   pthread_create    #include <pthread.h>   ...

  2. memset赋初值的运用

    int ”较“的原则:加法不爆. 极大值:0x7f 较大值:0x3f 较小值:0xc0 极小值:0x80 long long ”较“的原则:加法不爆. 极大值:0x7f 较大值:0x3f 较小值:0x ...

  3. Git使用02--branch分支, tag版本, 忽略文件 .gitingore

    一.分支 # 查看分支 git branch # 创建分支 git branch 分支名 # 切换分支 git checkout name # 创建并切换分支 git checkout -b name ...

  4. L1 loss L2 loss

    https://www.letslearnai.com/2018/03/10/what-are-l1-and-l2-loss-functions.html http://rishy.github.io ...

  5. 【luogu P3398 仓鼠找sugar】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3398 辣鸡树剖1300ms 倍增大法吼啊 #include <cstdio> #include ...

  6. 【luogu P2299 Mzc和体委的争夺战】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2299#sub 裸的迪杰斯特拉(我是在考试前复习一下板子) #include<iostream> ...

  7. 中小学信息学奥林匹克竞赛-理论知识考点--IP地址

    IP地址同身份证号一样,具有唯一性! 每个人都有一个唯一的标识:身份证号. 互联网中的计算机也一样,具有一个唯一的标识:IP地址. IP地址是一个32位的二进制数,通常被分割为4个“8位二进制数”(也 ...

  8. Java 加密PDF设置密码并添加水印

    /** * Project Name:XXX * File Name:EncryptLogFile.java * Date:2016-6-12上午11:56:38 * Copyright (c) 20 ...

  9. linux多线程编程基本操作(2)

    linux c多线程总结: :关于线程和进程 a:使用多线程的理由之一是和进程相比,它是一种非常"节俭"的多任务操作方式.我们知道,在Linux系统下,启动一个新的进程必须分配给 ...

  10. nineoldandroid 详细使用并且实现drawerlayout侧滑动画

    nineoldandroid.view.ViewHelpe是一个为了兼容3.0以下的一个动画开源库 相关函数解读:(第一个参数都为动画对象,第二个为动画属性值的变化表达式) ViewHelper.se ...