博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【100题】第四十五题 雅虎面试两道题(矩阵判断、数组划分)
阅读量:6284 次
发布时间:2019-06-22

本文共 3139 字,大约阅读时间需要 10 分钟。

一,对于一个整数对于一个整数矩阵矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一,现给出一正数矩阵,判断其是否能够由一个全零矩阵经过上述运算得到。

       分析:对任意一个位置,他的值不大于周围(上下左右)4个临格的数值的和,如果大于则该矩阵不能由全零矩阵得到

       解法一:可能是我能想到的最复杂的方法

                      1)将二维数组根据行优先原则,变为一维数组。

                      2)然后对一维数组进行排序,取不为零的值,将元素对应的值拆分成对应个数该元素,然后全排列。这样得到所有可能的矩阵元素递减策略。例如A[0][0] = 3 则对应 A[0] 拆分成3个A[0]

                      3)对上述排列逐一判断

                            1>如果相邻元素在二维数组中不“相邻”则排除

                            2>如果同一个元素相邻则排除

                            3>遍历到某个排列时,正好遍历完则返回正确     

                                 如果遍历完整个全排列,也没有得到正确结果,则说明不能由全零矩阵得到整形 矩阵                        解法二:优化解法一

                     1)先扫描整个二维数组,如果某个元素值大于其周围元素值和,则返回错误

                     2)然后利用动态规划,递归的思路。

                           自己写的递归算法,不知有无错误。敬请斧正!!!谢谢!!!

#include 
using namespace std;#define cols 2#define rows 2int test(int a[][cols]){ int n=0; for(int i=0;i
=0)&&(j-1>=0)&&(a[i-1][j-1]>0)) { flag=1; a[i-1][j-1]--; if(test(a)==1) return 1; aroundTest(a,i-1,j-1); a[i-1][j-1]++; } if((i-1>=0)&&(a[i-1][j]>0)) { flag=1; a[i-1][j]--; if(test(a)==1) return 1; aroundTest(a,i-1,j); a[i-1][j]++; } if((i-1>=0)&&(a[i-1][j+1]>0)) { flag=1; a[i-1][j+1]--; if(test(a)==1) return 1; aroundTest(a,i-1,j+1); a[i-1][j+1]++; } if((j-1>=0)&&(a[i][j-1]>0)) { flag=1; a[i][j-1]--; if(test(a)==1) return 1; aroundTest(a,i,j-1); a[i][j-1]++; } if((a[i][j+1]>0)) { flag=1; a[i][j+1]--; if(test(a)==1) return 1; aroundTest(a,i,j+1); a[i][j+1]++; } if((a[i+1][j-1]>0)) { flag=1; a[i+1][j-1]--; if(test(a)==1) return 1; aroundTest(a,i+1,j-1); a[i+1][j-1]++; } if((a[i][j+1]>0)) { flag=1; a[i][j+1]--; if(test(a)==1) return 1; aroundTest(a,i,j+1); a[i][j+1]++; } if((a[i+1][j+1]>0)) { flag=1; a[i+1][j+1]--; if(test(a)==1) return 1; aroundTest(a,i+1,j+1); a[i+1][j+1]++; } if(flag==0) return 0; }void distiguish(int a[][cols])//i为行,n为每行元素个数 { int result; for(int i=0;i
0) { a[i][j]--; result=aroundTest(a,i,j); if(result==1) { cout<<"YES"<
附:退出单重循环用break;

       退出双重或多重循环用 return;

                 

二,一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
     
比如{32436}可以分成{32436}     m=1; 
             {3,6} {2,4,3}   m=2
             {3,3} {2,4} {6} m=3

      所以m的最大值为3

 

      分析:1)如果所有值的和sum(a[0]-a[n])/m != 0则直接退出

                      如果数组最大值> sum/m  则m不能再增加了

                 2)主要用的思想为,深度优先遍历,优化用剪枝法。

                       对于 递归算法  bool dfs(int res,int cpl,int level)

                                res 为当前要凑齐长度的数组中,已经添加元素后的长度

                                cpl 为已经添加好的组数

                        每次先判断当前数组是否已经符合 分组条件,符合则cpl+1

                        添加某个未使用的元素有三种情况

                                        1> 添加后 等于 分组后每组大小  这时试着添加后,进行递归。如果最终返回true 则成功,否则,不能添加本元素到当前小组

                                         2> 添加后 小于 分组后大小 ,也试着添加,然后同上

                                         3> 添加后大于 分组后大小,则舍弃

                        如果全程没有返回一个ture 则该分组不正确

         

     代码:

#include
#include
using namespace std;int n; //小棒总数int len; //当前枚举的原棒长度int parts; //当前组合的原棒数int max; //最长小棒的长度int sum; //所有小棒的总长int a[100]; //存储小棒相关信息bool used[100]; //标记小棒是否使用bool pt(int a,int b){ return a>b;}//res 为每组长度和 cpl 为组数 bool dfs(int res,int cpl,int level)//res:当前已组合进去的木棒的长度 cpl:组合进去的小木棒的条数{ int i; if(res==len)//本组够长 { res = 0; cpl++; } if(cpl == parts)//组数已够 return true; for(i=level;i
 

转载于:https://www.cnblogs.com/secbook/archive/2012/08/20/2654962.html

你可能感兴趣的文章
索引失效 ORA-01502
查看>>
Oracle取月份,不带前面的0
查看>>
Linux Network Device Name issue
查看>>
IP地址的划分实例解答
查看>>
如何查看Linux命令源码
查看>>
运维基础命令
查看>>
入门到进阶React
查看>>
SVN 命令笔记
查看>>
检验手机号码
查看>>
重叠(Overlapped)IO模型
查看>>
Git使用教程
查看>>
使用shell脚本自动监控后台进程,并能自动重启
查看>>
Flex&Bison手册
查看>>
solrCloud+tomcat+zookeeper集群配置
查看>>
/etc/fstab,/etc/mtab,和 /proc/mounts
查看>>
Apache kafka 简介
查看>>
socket通信Demo
查看>>
技术人员的焦虑
查看>>
js 判断整数
查看>>
建设网站应该考虑哪些因素
查看>>