【算法】网易2017校园招聘笔试程序题(分田地)
2016-08-04 11:17
801 查看
题目
牛牛和15个朋友玩打土豪分田地的游戏,牛牛决定让你来分田地,地主的田地可以看成是一个矩形,每个位置有一个价值。分割田地的方法是横竖各切三刀,分成16份,作为领导干部,牛牛总是会选择其中总价值最小的一份田地,作为牛牛最好的朋友,你希望牛牛取得的田地的价值和尽可能大,你知道这个值最大可以是多少吗?输入描述
每个输入包含1个测试用例。每个测试用例的第一行包含两个整数n和m(1 <= n,m <= 75),表示田地的大小,接下来的n行,每行包含m个0-9之间的数字,表示每块位置的价值。输出描述
输出一行表示牛牛所能取得的最大的价值。结果
输入例子4 4
3 3 3 2
3 2 3 3
3 3 3 2
2 3 2 3
输出例子
2
算法思路
咋一看这个题目不是傻逼嘛,只求矩阵最小值不就可以么。。。细思之后才发现自己傻逼。题目的意思是对于m*n的矩阵,横竖三刀,也就是十六份中,牛牛得最小值。但是因为有不同的切法,所以在所有分法中,牛牛要得到最小值中最大的那个,因为他朋友希望牛牛能拿的价值尽可能大。那这个题目如何解呢?因为横竖切法太多了,都不知道如何下手,暴力破解也不是很好办啊。但是冷静之后想了下,其实思路我觉得也挺简单。
1)就是对于m*n的矩阵,首先找到最小值的那块,你想你希望牛牛拿的多,那这块肯定是要和它周边分在一起的,那对于最小这块可以和它分在一起的,无非就是向上合并,或者向下合并,或者向左合并,或者向右合并嘛,这样就得到一个行或者列少一行的新矩阵。
2)对于新矩阵再次找最小块,然后是向上合并,或者向下合并,或者向左合并,或者向右合并,完全就是上面的一个新轮回。
3)直到矩阵合并为4*4的矩阵,其中最小的就是牛牛获得最小值。
需要注意的是,每一次合并都不能确定一定是往某一个方向合并,所以必须每个方向都合并,这样每种情况下最后会产生不一样的4*4矩阵,也就是能得到若干最小值,而牛牛最终得到的价值就是这些最小值中最大的。
算法实现
public class Main{ public static int minVal; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt()-1;//N行 int m = sc.nextInt()-1;//M列 int matrix[][] = new int[n+1][m+1]; int minpos[]=new int[2];//记录矩阵中最小值的位置 for(int i=0;i<=m;i++){ for(int j=0;j<=n;j++){ matrix[i][j]=sc.nextInt(); } } getMinpos(matrix,m,n,minpos);//获取矩阵中最小值位置 minVal=matrix[minpos[0]][minpos[1]];//初始化牛牛获得的最小价值 System.out.println("所有分法:"); getMaxVal(matrix,m,n,minpos);//分田过程 System.out.println("最终牛牛获得的价值:"+minVal);//输出牛牛获得的价值 } private static void getMaxVal(int[][] matrix, int m, int n, int[] minpos) { int oldMatrix[][] = new int[m+1][n+1]; oldMatrix=matrix;//保存原矩阵,回溯返回到这时还需要用原来的矩阵而不是被子过程改变的矩阵 int m0 = minpos[0]; int n0 = minpos[1]; //最后得到4*4返回 if(m==n&&m==3){ for(int i=0;i<=3;i++){ System.out.println(java.util.Arrays.toString(matrix[i])); } System.out.println(); return; } //向上合并 if(m0>0&&m>3){ matrix=mergeMatrix(matrix,m,n,m0-1,n,minpos,1); getMaxVal(matrix,matrix.length-1,matrix[0].length-1,minpos); } matrix=oldMatrix; //向下合并 if(m0<m&&m>3){ matrix=mergeMatrix(matrix,m,n,m0,n,minpos,1); getMaxVal(matrix,matrix.length-1,matrix[0].length-1,minpos); } matrix=oldMatrix; //向左合并 if(n0>0&&n>3){ matrix=mergeMatrix(matrix,m,n,m,n0-1,minpos,-1); getMaxVal(matrix,matrix.length-1,matrix[0].length-1,minpos); } matrix=oldMatrix; //向右合并 if(n0<n&&n>3){ matrix=mergeMatrix(matrix,m,n,m,n0,minpos,-1); getMaxVal(matrix,matrix.length-1,matrix[0].length-1,minpos); } } private static int[][] mergeMatrix(int[][] matrix, int m, int n,int mergem,int mergen, int[] minpos,int flag) { int[][] temp=null; if(flag==1){//向上合并 或 向下合并 temp = new int[m][n+1]; for(int i=0;i<=m;i++){ for(int j=0;j<=n;j++){ if(i<mergem){ temp[i][j] = matrix[i][j]; } else if(i==mergem){ temp[i][j] = matrix[i][j]+matrix[i+1][j]; }else{ temp[i-1][j] = matrix[i][j]; } } if(i==mergem){ i++; } } }else if(flag==-1){//向左合并 或 向右合并 temp = new int[m+1] ; for(int i=0;i<=m;i++){ for(int j=0;j<=n;j++){ if(j<mergen){ temp[i][j]=matrix[i][j]; } else if(j==mergen){ temp[i][j]=matrix[i][j]+matrix[i][j+1]; j++; }else{ temp[i][j-1]=matrix[i][j]; } } } } //合并后的矩阵求其中最小的位置 getMinpos(temp,temp.length-1,temp[0].length-1,minpos); return temp; } //获取矩阵最小值位置 private static void getMinpos(int[][] matrix,int m,int n,int[] minpos) { int min = Integer.MAX_VALUE; for(int i=0;i<=m;i++){ for(int j=0;j<=n;j++){ if(matrix[i][j]<min){ min=matrix[i][j]; minpos[0]=i; minpos[1]=j; } } } if(minVal<min){ minVal=min; } } }
示例
注意我的输入矩阵是带空格的,原题是不带空格,所以还需要以字符串输入再切分。5 5 3 3 3 2 2 3 2 2 3 3 3 3 3 3 2 1 1 1 1 1 2 2 2 2 2 所有分法: [3, 3, 5, 2] [3, 2, 5, 3] [4, 4, 8, 3] [2, 2, 4, 2] [3, 3, 3, 4] [3, 2, 2, 6] [4, 4, 4, 7] [2, 2, 2, 4] [3, 3, 5, 2] [3, 2, 5, 3] [3, 3, 6, 2] [3, 3, 6, 3] [3, 3, 3, 4] [3, 2, 2, 6] [3, 3, 3, 5] [3, 3, 3, 6] [6, 3, 2, 2] [5, 2, 3, 3] [8, 4, 4, 3] [4, 2, 2, 2] [6, 3, 2, 2] [5, 2, 3, 3] [6, 3, 3, 2] [6, 3, 3, 3] 最终牛牛获得的价值:2
结语
因为牛客网还没出真题oj所以无法知道是否通过,如果有人发现算法有误,欢迎拍砖!相关文章推荐
- 分田地
- 统计二进制数中1的个数
- java map转bean
- C#线程
- Laravel与Repository Pattern(仓库模式)
- django发送邮件相关配置
- Struts2输入校验
- 结合 category 工作原理分析 OC2.0 中的 runtime
- C语言调试打印
- spring-autowire机制
- php的curl提交总结
- C++指针详解
- 开启JAVA自学新篇章
- 开启JAVA自学新篇章
- C++基础:string和vector操作
- java web 学习笔记(一)WEB开发技术发展
- frontpage 正则 查找与替换
- JAVA字符串格式化-String.format()的使用
- 八大排序算法 Java、Python、C++实现 -- 希尔排序
- Qt控件QTableWidget