R语言编程:阿里推笔试题之一
来源:互联网 发布:excel中vba编程 编辑:程序博客网 时间:2024/06/03 18:04
R语言编程:阿里推笔试题之一
题目
沐哲是一个菜鸟仓库的一个拣货员,但他有非常个怪异的习惯。每次拣货的重量都要比之前拣的一个轻,每次拣到货后都可以得到1块钱,沐哲想知道这样最多能赚多少钱
32 34 7 33 21 2
13 12 3 11 26 36
16 30 22 1 24 14
20 23 25 5 19 29
27 15 9 17 31 4
6 18 8 10 35 28
沐哲可以从仓库的某个货架开始拣货,下一步可以往上走,也可以往下走,当然,向左向右也可以,但必须使得下一个货物重量减小,才会去拣。在上面的仓库中,一条可拣货的路径为 25-22-3。当然30-23-20-16-13-12-3可以拣的货更多。这也是赚钱最多的一条路径.
要求
输入行数、列数和数据矩阵,输出所赚的最大钱数。
例子:
输入:
6 6
32 34 7 33 21 2
13 12 3 11 26 36
16 30 22 1 24 14
20 23 25 5 19 29
27 15 9 17 31 4
6 18 8 10 35 28
输出:
7
求解过程:
本人想出两张思路来设计程序,不足之处欢迎指出,谢谢!
方法一:暴力求解
说明暴力求解在于求货架上每个元素可以走的最大步数,这里不需要存储每一步的坐标,只要判断基于第k步的所有地址下能否存在第k+1步的地址,则意味着可以走到第k+1步,直至不满足条件为止,此时的k即为最大步数.
函数:
参数说明:
n.row: 表示原始重量矩阵的行数
n.col: 表示原始重量矩阵的列数
start.i: 表示初始货物的横坐标
start.j: 表示初始货物的纵坐标
M:表示初始重量矩阵
Num_Step <- function(n.row, n.col, start.i, start.j, M){ i <- start.i j <- start.j s <- 1 # 用于计数 next_step <- list(c(i,j)) # 用于存储第K个节点(s步)可选择的货物坐标(列表) repeat{ index <- list() #用于存储s步可选择的下一个货物的坐标,满足条件时则赋予给next_step # 第s步有k个选择,每个选择都意味着下一步的货物位置,该循环基于第s步以寻找第s+1步的位置 for(k in 1:length(next_step)){ i <- next_step[[k]][1] # 提取第k个选择的横坐标 j <- next_step[[k]][2] # 提取第k个选择的纵坐标 # 判断第k个选择的垂直向上的货物是否满足 if(i==1){ next_up <- NA }else if(M[i,j]>M[i-1,j]){ next_up <- c(i-1,j) }else{ next_up <- NA } # 判断第k个选择的垂直向下的货物是否满足 if(i==n.row){ next_down <- NA }else if(M[i,j]>M[i+1,j]){ next_down <- c(i+1,j) }else{ next_down <- NA } # 判断第k个选择的水平向左的货物是否满足 if(j==1){ next_left <- NA }else if(M[i,j]>M[i,j-1]){ next_left <- c(i,j-1) }else{ next_left <- NA } # 判断第k个选择的水平向右的货物是否满足 if(j==n.col){ next_right <- NA }else if(M[i,j]>M[i,j+1]){ next_right <- c(i,j+1) }else{ next_right <- NA } # 将第k选择时第s+1步满足条件的位置存储下来 next_id <- list(next_up, next_down, next_left, next_right,NA) next_id <- next_id[-which(is.na(next_id))] # 剔除空值 # 将所有k各选择的s+1步满足条件的位置存储下来 index <- c(index, next_id) } # 判断s+1步是否有效,即从s到s+1步有没有路可走 if(length(index)==0){ break } # 如果有路可走,则将s+1步所有的位置信息赋给next_step next_step <- index s <- s+1 # 用于计数(步长) } return(s) # 这里步长即为货架上以每个货物为初始值时的最大收益 }
测试结果
## 计算所有元素为起始点的最大收益BL_step <- function(n.row, n.col, M){ price <- matrix(NA, n.row, n.col) for(start.i in 1:n.row){ for(start.j in 1:n.col){ price[start.i,start.j] <- Num_Step(n.row, n.col, start.i, start.j, M) } } return(price)}## 以题目中给的货架为例:M <-matrix(c(32, 34, 7, 33, 21, 2, 13, 12, 3, 11, 26, 36, 16, 30, 22, 1, 24, 14, 20, 23, 25, 5, 19, 29, 27, 15, 9, 17, 31, 4, 6, 18, 8, 10, 35, 28),6,byrow = T) n.row <- nrow(M)print(paste("n.row",n.row, sep = "="))n.row = 6n.col <- ncol(M)print(paste("n.col",n.col, sep = "="))n.col = 6
输出收益矩阵
BL_step(n.row, n.col, M) [,1] [,2] [,3] [,4] [,5] [,6][1,] 4 5 2 3 2 1[2,] 3 2 1 2 5 6[3,] 4 7 2 1 4 1[4,] 5 6 7 2 3 4[5,] 6 3 2 3 4 1[6,] 1 4 1 2 5 2
方法二:动态规划
说明:利用动态规划的思想,从最大步数最少的元素找起,那么最大步数为s的元素的上下左右四个位置一定存在第s-1步的元素.以此为判断条件结合辅助条件来给矩阵赋值.
算法步骤:
1.令P为一个与初始货架重量矩阵同维度的步数矩阵(初始元素都为0)
2.s=1,即最大步长为1开始
3.矩阵中元素满足上下左右位置的元素都大于该元素,则该元素的最大步长为1
4.从s=2开始,取矩阵中未赋值的元素(即=0的元素),进行逐个判断
5.判断条件1:该元素的上下左右四个元素中至少存在最大步长为(s-1)步的元素
6.判断条件2:若满足判断条件1,则上下左右除去(s-1)元素外,若其余位置比该元素小的元素都已经赋值,也即它只能被进入而不能超其他方向走;或者其余位置都比该元素大时,则该元素即为(s+1)步元素
7.重复3-6步,直至矩阵所以元素都已赋值时结束.
函数及结果
参数说明:
n.row: 初始矩阵的行数
n.col: 初始矩阵的列数
M:初始货架重量矩阵
LP_Step <- function(n.row, n.col, M){ p <- matrix(0, n.row, n.col) # 设置初始收益矩阵 s=1 # 收益为1(s用于计最大步数) ## 循环第s次,将矩阵元素最多能走的步数等于s步的赋值,直至所有元素填满为止. repeat{ step_id <- which(p==0, arr.ind = T) # 该步用于取未赋值的元素的位置 temp_step <- c() # 用于存储最大步数为s时的元素的坐标 ## 小循环对s步中未赋值的元素进行判断,是否满足为s+1步元素 for(k in 1:nrow(step_id)){ i <- step_id[k,1] j <- step_id[k,2] if(i==1){ up <- NA }else{ up <- c(i-1, j) } if(i==n.row){ down <- NA }else{ down <- c(i+1, j) } if(j==1){ left <- NA }else{ left <- c(i, j-1) } if(j==n.col){ right <- NA }else{ right <- c(i, j+1) } # 将附件的元素的位置存储下来,并取值,取步数值 round_id <- rbind(up, down, left, right,NA) round_id <- round_id[-which(is.na(round_id), arr.ind = T)[,1],] round_value <- M[round_id] round_p <- p[round_id] id <- which(round_value < M[i,j])# 比该元素小的附近元素的位置 juge_last <- which(round_p==(s-1)) # 取附近最大步数为s-1的元素用于判断 if(length(juge_last)>0){ # 判断条件1 if(s==1){ # 对第一步单独考察 if(M[i,j] <= min(round_value)){ temp_step <- rbind(temp_step,c(i,j)) } }else if(all(round_p[id]!=0, na.rm = T)){ # 判断条件2 temp_step <- rbind(temp_step,c(i,j)) } } } p[temp_step] <- s # 对步数矩阵赋值 ## 判断步数矩阵是否都赋值,是则结束,否则继续 if(length(which(p==0))==0){ break } s=s+1 # 计步 } return(p)}M <-matrix(c(32, 34, 7, 33, 21, 2, 13, 12, 3, 11, 26, 36, 16, 30, 22, 1, 24, 14, 20, 23, 25, 5, 19, 29, 27, 15, 9, 17, 31, 4, 6, 18, 8, 10, 35, 28),6,byrow = T) n.row <- nrow(M)n.col <- ncol(M)LP_Step(n.row, n.col, M) [,1] [,2] [,3] [,4] [,5] [,6][1,] 4 5 2 3 2 1[2,] 3 2 1 2 5 6[3,] 4 7 2 1 4 1[4,] 5 6 7 2 3 4[5,] 6 3 2 3 4 1[6,] 1 4 1 2 5 2
阅读全文
0 0
- R语言编程:阿里推笔试题之一
- 阿里算法内推笔试题
- 阿里前端内推笔试题
- 校园招聘-2017阿里C/C++研发工程师内推笔试编程题
- 阿里2017编程笔试题
- 2017阿里C/C++暑期实习生在线笔试附加题编程题之一。。
- 阿里内推实习生在线编程题
- 阿里内推编程测试题
- 搜狗校招笔试题编程之一
- 2017阿里内推笔试题--算法工程师(运筹优化)
- 【网易2017内推笔试编程题】
- 网易内推笔试编程题2
- 阿里2018校招笔试编程题
- R 语言入门之一
- 2015小米笔试/阿里内推面试
- CVTE、阿里内推笔试面试经历
- 2018秋招-阿里内推编程题
- 网易内推笔试编程题-字符串子序列判断
- Funny Function
- Spinner弹出框遮挡住显示框的解决办法
- 欢迎使用CSDN-markdown编辑器
- add-apt-repository问题
- 1.1 数据结构
- R语言编程:阿里推笔试题之一
- 第二天总结
- java中的抽象类
- Unity3D之UI按键绑定事件(六)
- C++开源项目
- 神经网络与深度学习 1.5 使用梯度下降算法进行学习
- 排版的一点小注意
- 对象和类的关系
- 正则表达式30分钟入门教程