算法习题45:对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一;;;一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
来源:互联网 发布:淘宝上怎样搜索店铺 编辑:程序博客网 时间:2024/04/28 16:55
.雅虎:
1.对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一,
现给出一正数矩阵,判断其是否能够由一个全零矩阵经过上述运算得到。
2.一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
比如{3,2,4,3,6} 可以分成{3,2,4,3,6} m=1;
{3,6}{2,4,3} m=2
1.对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一,
现给出一正数矩阵,判断其是否能够由一个全零矩阵经过上述运算得到。
2.一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
比如{3,2,4,3,6} 可以分成{3,2,4,3,6} m=1;
{3,6}{2,4,3} m=2
{3,3}{2,4}{6} m=3 所以m的最大值为3
----------------------------------------------------------------------
1:这题我我们自己试着模拟一遍,发现有点类似,扫雷,但是还是有差别的。
我想到了两个制约条件:
(1)某个非零元的值一定小于等于它上下左右的和
(2)整个矩阵的和必须是偶数(因为加1就跟着加另一个1,肯定是偶数)
似乎这两个条件就可以了,难道是必要条件???
我想不到从数学上证明,希望有人能给个清晰的答案。
2:这题我们应该逐步分解,
首先是平均分问题,我们可以分成几份呢?当然最多就是每个元素单独出来,所以最多n份;
其次,是不是1--n这么多都可以呢?不是的,必须总和能够整除份数才行
如果现在需要分成m份,而且能够被数组总和整除,那么就可以计算了,
接下来就是一个数组里找出某几个元素和为total/m 的序列了,
这里类似背包算法,需要用到递归
我这里就引用下面这篇博客代码了,写得比我整齐多了。。。
http://blog.csdn.net/peng_weida/article/details/7741888
#include <cstdio>#include <cstdlib>#define NUM8int maxShares(int a[], int n);//aux[i]的值表示数组a中第i个元素分在哪个组,值为0表示未分配//当前处理的组的现有和 + goal的值 = groupsumint testShares(int a[], int n, int m, int sum, int groupsum, int aux[], int goal, int groupId);int main(){//int a[] = {2, 6, 4, 1, 3, 9, 7, 5, 8, 10};//int a[]={2,2,3,5,6,6};int a[]={1,1,2,2,3,4,5,6};//打印数组值printf("数组的值:");for (int i = 0; i < NUM; i++)printf(" %d ", a[i]);printf("\n可以分配的最大组数为:%d\n", maxShares(a, NUM));return 0;}int testShares(int a[], int n, int m, int sum, int groupsum, int aux[], int goal, int groupId){if (goal < 0)return 0;if (goal == 0){groupId++;goal = groupsum;if (groupId == m+1)return 1;}for (int i = 0; i < n; i++){if (aux[i] != 0)continue;aux[i] = groupId;if (testShares(a, n, m, sum, groupsum, aux, goal-a[i], groupId))return 1;aux[i] = 0;//a[i]分配失败,将其置为未分配状态}return 0;}int maxShares(int a[], int n){int sum = 0;int *aux = (int *)malloc(sizeof(int) * n);for (int i = 0; i < n; i++)sum += a[i];for (int m = n; m >= 2; m--){if (sum%m != 0)continue;for (int i = 0; i < n; i++)aux[i] = 0;if (testShares(a, n, m, sum, sum/m, aux, sum/m, 1)){//打印分组情况printf("\n分组情况:");for (int i = 0; i < NUM; i++)printf(" %d ", aux[i]);free(aux);aux = NULL;return m;}}free(aux);aux = NULL;return 1;}
我的思路和上面差不多,不过上面这个方法借助辅助数组aux[]来表示被访问和分配组别这两个信息 这个技巧不错
而我却是用一个数组来记录当前累加的数字,而是否分配过则通过更改原数组值为0来实现
我的思路比较乱。。
#include <iostream>using namespace std;void Print(int *ans, int index);void H(int k, int sum, int n, int *arr, int dst, int *ans, int index);bool H2(int k, int sum, int n, int *arr, int dst, int *ans, int index, int* m);int main() {int ans[8];int index=0;int dst;//每组需要达到的和int i =0;int n = 8;//数组元素个数int m = n;int total = 24;//这里是数组的总和for(m=n;m>0;m--){int test[] = {1,1,2,2,3,4,5,6};int groupN = m;if(total%m == 0)dst = total/m;else continue;if(test[n-1]>dst)continue;cout<<"分成"<<m<<"组,"<<"每组和为"<<dst<<endl;for(i=n-1;i>=0;i--){ans[0] = test[i];index = 1;if(ans[0] == dst){Print(ans, index);groupN--;continue;}if(ans[0] > dst)continue;H2(0, ans[0], i, test, dst, ans, index, &groupN);}if(groupN != 0)cout<<"失败"<<endl;elsecout<<"成功"<<endl;cout<<"***************"<<endl;}return 0;}/* * k表示当前访问到第几个元素 * sum表示当前已累加的和 * arr表示原数组 * dst我们需要达到的和 * ans记录答案 * m 用来表示是否分组成功,每成功一组就减一,直至为0则成功 */bool H2(int k, int sum, int n, int *arr, int dst, int *ans, int index, int* m){int i = k;for(;i<n;i++){if(arr[i] == 0)continue;int temp = sum + arr[i];if(temp<dst){ans[index++] = arr[i];arr[i] = 0;if(!H2(i+1, temp, n, arr, dst, ans, index,m))return false;index--;arr[i] = ans[index];}else if(temp == dst){ans[index++] = arr[i];arr[i] = 0;Print(ans, index);(*m)--;index--;return false;}else{return true;}}return true;}void Print(int *ans, int index){int i = 0;for(i=0;i<index;i++)cout<<ans[i]<<" ";cout<<endl;}
分成4组,每组和为66 5 1 4 2 3 1 2 成功***************分成3组,每组和为86 1 1 5 3 4 2 2 成功***************分成2组,每组和为126 1 1 2 2 5 3 4 成功***************分成1组,每组和为246 1 1 2 2 3 4 5 成功***************
- 算法习题45:对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一;;;一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- 对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一
- 对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一, 现给出一正数矩阵,判断其是否能够由一个全零矩阵经过上述运算得到。
- 对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一,现给出一正数矩阵,判断其是否能够由一个全零矩阵经过上述运算得到
- 对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一, 现给出一正数矩阵,判断其是否能够由一个全零矩阵经过上述运算得到。
- 对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右),某一个元素也加一,现给出一正数矩阵,判断其是否能够由一个全零矩阵经过上述运算得到。
- 45一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- 一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- 一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- 一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- 一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- 一个整数数组,长度为n,将其分为m 份,使各份的和相等,求m 的最大值
- 一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- 一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- 一个整数数组,长度为n,将其分为m 份,使各份的和相等,求m 的最大值
- 一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值。
- 每日一道算法题:一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- 【微软谷歌面试100题--【45】一个整数数组,长度为n,将其分为m 份,使各份的和相等,求m 的最大值
- Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
- POJ1850-组合数学
- 分析竞争对手对网站优化的好处
- 黑马程序员-异常
- mac 下 protocol buffer的安装
- 算法习题45:对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一;;;一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- Windows 8 JavaScript Metro Application–Getting Started
- Android 4.4特性说明(持续更新)
- Ubuntu Server 12.04日版apt-get源
- Asp.net控件开发学习笔记(四)---Asp.net服务端状态管理
- Using PhoneGap in Windows Store Applications
- 标题dfdfdfdsfgdgfdggggggggggggggggggggggggggggggggggggdfdf
- 【第四章—第七章】【初识C++ Accelerated C++ 学习笔记】
- 控制台输入输出重定向