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

这道题,是我目前为止做过的最最最最最麻烦、最繁琐的题目了。

思路:

把输入的矩阵一步步还原成 0 矩阵

一个数字,只可能伴随着它上下左右四个方向的数字变化。

①如果数字比它周围四个数的和要大,那么一定不满足条件。

②如果数字小于等于四周的数字和,且其四周仅有一个数字不为0: 不为0的那个周围数字的大小 -= 当前数字大小,将当前数字置零。  因为当前数字仅可能是那个不为0的数字引起的。

③如果数字等于四周的数字和,且其四周仅有多个个数字不为0:当前与四周的数字均置0。

④如果数字小于四周的数字和,且其四周仅有多个个数字不为0:无法判断,循环继续还原。

思路不难,但是对于矩阵的四个角、四条边和中间必须分开处理,让整个代码显得又臭又长!但实际上,跟一份代码被copy了9遍差不多。我还没有什么化简的方法。如果有人知道,希望可以告诉我。

/*
45.雅虎(运算、矩阵):
1.对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)
某一个元素也加一,现给出一正数矩阵,判断其是否能够由一个全零矩阵经过上述运算得到。
*/
#include <stdio.h>bool canBeCreatedbyZero(int ** M, int row, int col)
{bool flag = false;do {flag =false;for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++){//打印每一次处理后的矩阵情况printf("\n");for (int r = 0; r < row; r++){for(int c = 0; c < col; c++){printf("%d", *((int *)M + r * col + c));}printf("\n");}if ((i == 0) &&(j != 0 && j != col - 1)) //最上边
                {int * r = (int *)M + i * col;int * r1 = (int *)M + (i + 1) * col; if((r[j - 1] != 0 || r[j] != 0 || r[j + 1] != 0 || r1[j] != 0)) //只在有非零元素的时候才做下面处理
                    {    flag = true;int has[3][2];int hasnum = 0; //该中心点上下左右有几个不为0的数字int sum = 0; //该中心点四周的数字相加的值if (r[j - 1] != 0){has[hasnum][0] = i;has[hasnum][1] = j - 1;hasnum++;}if (r[j + 1] != 0){has[hasnum][0] = i;has[hasnum][1] = j + 1;hasnum++;}if (r1[j] != 0){has[hasnum][0] = i + 1;has[hasnum][1] = j;hasnum++;}sum = r[j - 1] + r[j + 1] + r1[j];if (r[j] > sum) //数字大于周围的和 返回false
                        {return false;}else if(hasnum == 1) //旁边只有一个不为0的 中心数字与旁边数字同步减少
                        {int t = r[j];r[j] = 0;*((int *)M + has[0][0] * col + has[0][1]) -= t;}else if(r[j] == sum) //中心数字与旁边不为0的数字和相等
                        {for(int ii = 0; ii < hasnum; ii++){*((int *)M + has[ii][0] * col + has[ii][1]) = 0;}r[j] = 0;}}}else if((i == row - 1) &&(j != 0 && j != col - 1)) //最下边
                {int * r_1 = (int *)M + (i - 1) * col;int * r = (int *)M + i * col;if((r_1[j] != 0 || r[j - 1] != 0 || r[j] != 0 || r[j + 1] != 0)) //只在有非零元素的时候才做下面处理
                    {    flag = true;int has[4][2];int hasnum = 0; //该中心点上下左右有几个不为0的数字int sum = 0; //该中心点四周的数字相加的值if (r_1[j] != 0){has[hasnum][0] = i - 1;has[hasnum][1] = j;hasnum++;}if (r[j - 1] != 0){has[hasnum][0] = i;has[hasnum][1] = j - 1;hasnum++;}if (r[j + 1] != 0){has[hasnum][0] = i;has[hasnum][1] = j + 1;hasnum++;}sum = r_1[j] + r[j - 1] + r[j + 1];if (r[j] > sum) //数字大于周围的和 返回false
                        {return false;}else if(hasnum == 1) //旁边只有一个不为0的 中心数字与旁边数字同步减少
                        {int t = r[j];r[j] = 0;*((int *)M + has[0][0] * col + has[0][1]) -= t;}else if(r[j] == sum) //中心数字与旁边不为0的数字和相等
                        {for(int ii = 0; ii < hasnum; ii++){*((int *)M + has[ii][0] * col + has[ii][1]) = 0;}r[j] = 0;}}}else if ((j == 0) &&(i != 0 && i != row - 1)) //最左边
                {int * r_1 = (int *)M + (i - 1) * col;int * r = (int *)M + i * col;int * r1 = (int *)M + (i + 1) * col; if((r_1[j] != 0 || r[j] != 0 || r[j + 1] != 0 || r1[j] != 0)) //只在有非零元素的时候才做下面处理
                    {    flag = true;int has[4][2];int hasnum = 0; //该中心点上下左右有几个不为0的数字int sum = 0; //该中心点四周的数字相加的值if (r_1[j] != 0){has[hasnum][0] = i - 1;has[hasnum][1] = j;hasnum++;}if (r[j + 1] != 0){has[hasnum][0] = i;has[hasnum][1] = j + 1;hasnum++;}if (r1[j] != 0){has[hasnum][0] = i + 1;has[hasnum][1] = j;hasnum++;}sum = r_1[j] + r[j + 1] + r1[j];if (r[j] > sum) //数字大于周围的和 返回false
                        {return false;}else if(hasnum == 1) //旁边只有一个不为0的 中心数字与旁边数字同步减少
                        {int t = r[j];r[j] = 0;*((int *)M + has[0][0] * col + has[0][1]) -= t;}else if(r[j] == sum) //中心数字与旁边不为0的数字和相等
                        {for(int ii = 0; ii < hasnum; ii++){*((int *)M + has[ii][0] * col + has[ii][1]) = 0;}r[j] = 0;}}}else if ((j == col - 1) &&(i != 0 && i != row - 1)){int * r_1 = (int *)M + (i - 1) * col;int * r = (int *)M + i * col;int * r1 = (int *)M + (i + 1) * col; if((r_1[j] != 0 || r[j - 1] != 0 || r[j] != 0 || r1[j] != 0)) //只在有非零元素的时候才做下面处理
                    {    flag = true;int has[4][2];int hasnum = 0; //该中心点上下左右有几个不为0的数字int sum = 0; //该中心点四周的数字相加的值if (r_1[j] != 0){has[hasnum][0] = i - 1;has[hasnum][1] = j;hasnum++;}if (r[j - 1] != 0){has[hasnum][0] = i;has[hasnum][1] = j - 1;hasnum++;}if (r1[j] != 0){has[hasnum][0] = i + 1;has[hasnum][1] = j;hasnum++;}sum = r_1[j] + r[j - 1] + r1[j];if (r[j] > sum) //数字大于周围的和 返回false
                        {return false;}else if(hasnum == 1) //旁边只有一个不为0的 中心数字与旁边数字同步减少
                        {int t = r[j];r[j] = 0;*((int *)M + has[0][0] * col + has[0][1]) -= t;}else if(r[j] == sum) //中心数字与旁边不为0的数字和相等
                        {for(int ii = 0; ii < hasnum; ii++){*((int *)M + has[ii][0] * col + has[ii][1]) = 0;}r[j] = 0;}}}else if ( i == 0 && j == 0) //左上角
                {int * r = (int *)M + i * col;int * r1 = (int *)M + (i + 1) * col; if(( r[j] != 0 || r[j + 1] != 0 || r1[j] != 0)) //只在有非零元素的时候才做下面处理
                    {    flag = true;int has[4][2];int hasnum = 0; //该中心点上下左右有几个不为0的数字int sum = 0; //该中心点四周的数字相加的值if (r[j + 1] != 0){has[hasnum][0] = i;has[hasnum][1] = j + 1;hasnum++;}if (r1[j] != 0){has[hasnum][0] = i + 1;has[hasnum][1] = j;hasnum++;}sum = r[j + 1] + r1[j];if (r[j] > sum) //数字大于周围的和 返回false
                        {return false;}else if(hasnum == 1) //旁边只有一个不为0的 中心数字与旁边数字同步减少
                        {int t = r[j];r[j] = 0;*((int *)M + has[0][0] * col + has[0][1]) -= t;}else if(r[j] == sum) //中心数字与旁边不为0的数字和相等
                        {for(int ii = 0; ii < hasnum; ii++){*((int *)M + has[ii][0] * col + has[ii][1]) = 0;}r[j] = 0;}}}else if (i == row - 1 && j == 0) //左下角
                {int * r_1 = (int *)M + (i - 1) * col;int * r = (int *)M + i * col;if((r_1[j] != 0|| r[j] != 0 || r[j + 1] != 0)) //只在有非零元素的时候才做下面处理
                    {    flag = true;int has[4][2];int hasnum = 0; //该中心点上下左右有几个不为0的数字int sum = 0; //该中心点四周的数字相加的值if (r_1[j] != 0){has[hasnum][0] = i - 1;has[hasnum][1] = j;hasnum++;}if (r[j + 1] != 0){has[hasnum][0] = i;has[hasnum][1] = j + 1;hasnum++;}sum = r_1[j] + r[j + 1];if (r[j] > sum) //数字大于周围的和 返回false
                        {return false;}else if(hasnum == 1) //旁边只有一个不为0的 中心数字与旁边数字同步减少
                        {int t = r[j];r[j] = 0;*((int *)M + has[0][0] * col + has[0][1]) -= t;}else if(r[j] == sum) //中心数字与旁边不为0的数字和相等
                        {for(int ii = 0; ii < hasnum; ii++){*((int *)M + has[ii][0] * col + has[ii][1]) = 0;}r[j] = 0;}}}else if (i == 0 && j == col - 1) //右上角
                {int * r = (int *)M + i * col;int * r1 = (int *)M + (i + 1) * col; if((r[j - 1] != 0 || r[j] != 0 || r1[j] != 0)) //只在有非零元素的时候才做下面处理
                    {    flag = true;int has[4][2];int hasnum = 0; //该中心点上下左右有几个不为0的数字int sum = 0; //该中心点四周的数字相加的值if (r[j - 1] != 0){has[hasnum][0] = i;has[hasnum][1] = j - 1;hasnum++;}if (r1[j] != 0){has[hasnum][0] = i + 1;has[hasnum][1] = j;hasnum++;}sum = r[j - 1] + r1[j];if (r[j] > sum) //数字大于周围的和 返回false
                        {return false;}else if(hasnum == 1) //旁边只有一个不为0的 中心数字与旁边数字同步减少
                        {int t = r[j];r[j] = 0;*((int *)M + has[0][0] * col + has[0][1]) -= t;}else if(r[j] == sum) //中心数字与旁边不为0的数字和相等
                        {for(int ii = 0; ii < hasnum; ii++){*((int *)M + has[ii][0] * col + has[ii][1]) = 0;}r[j] = 0;}}}else if (i == row - 1 && j == col - 1) //右下角
                {int * r_1 = (int *)M + (i - 1) * col;int * r = (int *)M + i * col;if(r_1[j] != 0 || r[j - 1] != 0 || r[j] != 0) //只在有非零元素的时候才做下面处理
                    {    flag = true;int has[4][2];int hasnum = 0; //该中心点上下左右有几个不为0的数字int sum = 0; //该中心点四周的数字相加的值if (r_1[j] != 0){has[hasnum][0] = i - 1;has[hasnum][1] = j;hasnum++;}if (r[j - 1] != 0){has[hasnum][0] = i;has[hasnum][1] = j - 1;hasnum++;}sum = r_1[j] + r[j - 1];if (r[j] > sum) //数字大于周围的和 返回false
                        {return false;}else if(hasnum == 1) //旁边只有一个不为0的 中心数字与旁边数字同步减少
                        {int t = r[j];r[j] = 0;*((int *)M + has[0][0] * col + has[0][1]) -= t;}else if(r[j] == sum) //中心数字与旁边不为0的数字和相等
                        {for(int ii = 0; ii < hasnum; ii++){*((int *)M + has[ii][0] * col + has[ii][1]) = 0;}r[j] = 0;}}}else if(i != 0 && i != row - 1 && j != 0 && j != col - 1) //非边界情况
                {int * r_1 = (int *)M + (i - 1) * col;int * r = (int *)M + i * col;int * r1 = (int *)M + (i + 1) * col; if((r_1[j] != 0 || r[j - 1] != 0 || r[j] != 0 || r[j + 1] != 0 || r1[j] != 0)) //只在有非零元素的时候才做下面处理
                    {    flag = true;int has[4][2];int hasnum = 0; //该中心点上下左右有几个不为0的数字int sum = 0; //该中心点四周的数字相加的值if (r_1[j] != 0){has[hasnum][0] = i - 1;has[hasnum][1] = j;hasnum++;}if (r[j - 1] != 0){has[hasnum][0] = i;has[hasnum][1] = j - 1;hasnum++;}if (r[j + 1] != 0){has[hasnum][0] = i;has[hasnum][1] = j + 1;hasnum++;}if (r1[j] != 0){has[hasnum][0] = i + 1;has[hasnum][1] = j;hasnum++;}sum = r_1[j] + r[j - 1] + r[j + 1] + r1[j];if (r[j] > sum) //数字大于周围的和 返回false
                        {return false;}else if(hasnum == 1) //旁边只有一个不为0的 中心数字与旁边数字同步减少
                        {int t = r[j];r[j] = 0;*((int *)M + has[0][0] * col + has[0][1]) -= t;}else if(r[j] == sum) //中心数字与旁边不为0的数字和相等
                        {for(int ii = 0; ii < hasnum; ii++){*((int *)M + has[ii][0] * col + has[ii][1]) = 0;}r[j] = 0;}}}}}}while(flag == true);return true;
}int main()
{int a[4][4] = {{0,1,0,0},{1,2,2,1},{0,1,3,0},{0,0,1,0}};bool f = canBeCreatedbyZero((int **)a, 4, 4);getchar();return 0;}

网上找答案:居然没有找到别人写好的代码。都是说个思路就完了!!

有说用最大流可以搞定 http://blog.csdn.net/lihappy999/article/details/7395934

有说匈牙利算法的

http://www.cnblogs.com/GoAhead/archive/2012/06/01/2531144.html 给了个方法 但我没看懂

最让我无语的是翻答案就得到这样一段话:

A assignment problem. Two ways to solve. 1: duplicate each cell to as many as its value,
do Hungarian algorithm. Denote the sum of the matrix as M, the edge number is 2M, so
the complexity is 2*M*M; 2: standard maximum flow. If the size of matrix is NxN, then the
algorithm using Ford Fulkerson algorithm is M*N*N.
too complex... I will do this when I have time...

【编程题目】对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一...相关推荐

  1. 2022-03-06:金币路径。 给定一个数组 A(下标从 1 开始)包含 N 个整数:A1,A2,……,AN 和一个整数 B。 你可以从数组 A 中的任何一个位置(下标为 i)跳到下标 i+1,i+

    2022-03-06:金币路径. 给定一个数组 A(下标从 1 开始)包含 N 个整数:A1,A2,--,AN 和一个整数 B. 你可以从数组 A 中的任何一个位置(下标为 i)跳到下标 i+1,i+ ...

  2. 算法训练 - 阿尔法乘积 计算一个整数的阿尔法乘积。对于一个整数x来说,它的阿尔法乘积是这样来计算的:如果x是一个个位数,那么它的阿尔法乘积就是它本身;否则的话,x的阿 尔法乘积就等于它的各位非0

    问题描述 计算一个整数的阿尔法乘积.对于一个整数x来说,它的阿尔法乘积是这样来计算的:如果x是一个个位数,那么它的阿尔法乘积就是它本身:否则的话,x的阿 尔法乘积就等于它的各位非0的数字相乘所得到的那 ...

  3. 输入一个字符串,内有数字和非数字字符,例如: A123x456 17960? 302tab5876 将其中连续的数字作为一个整数,依次存放到一数组a中。例如,123放在a[0],456放在a[1]……

    输入一个字符串,内有数字和非数字字符,例如: A123x456 17960? 302tab5876 将其中连续的数字作为一个整数,依次存放到一数组a中.例如,123放在a[0],456放在a[1]-- ...

  4. 习题 6.16 输入一个字符串,内有数字和非数字字符,例如: a123x456 17960? 302tab5876将其中连续的数字作为一个整数,依次存放到一数组a中。

    习题 6.16 输入一个字符串,内有数字和非数字字符,例如: a123x456 17960? 302tab5876将其中连续的数字作为一个整数,依次存放到一数组a中.例如,123存入在a[0],456 ...

  5. 输入一个字符串,内有数字和非数字字符,例如:A123x456 17960? 302tab5876,将其中连续的数字作为一个整数,依次存放到一数组a中。例如,123放在a[0],456放在a[1]...

    输入一个字符串,内有数字和非数字字符,例如:A123x456 17960? 302tab5876,将其中连续的数字作为一个整数,依次存放到一数组a中.例如,123放在a[0],456放在a[1]-统计 ...

  6. 【C】8.16输入一个字符串,内有数字和非数字字符,例如:A123x456 17960?302tab5876 ,将其中连续的数字作为一个整数,依次存放到一数组a中。例如:123放在a[0],456放在

    //输入一个字符串,内有数字和非数字字符,例如:A123x456 17960?302tab5876 //将其中连续的数字作为一个整数,依次存放到一数组a中. //例如:123放在a[0],456放在a ...

  7. 给定一个整数数组 nums 和一个整数目标值 target, 请你在该数组中找出和为目标值 target 的那两个整数, 并返回它们的数组下标

    题目要求: 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值 target 的那两个整数,并返回它们的数组下标. [注]从前往后进行匹配, 一旦匹配成功, 便结 ...

  8. 【汇编语言与计算机系统结构笔记02】整数的计算机表示与运算,C中的无符号字符(unsigned)和带符号字符(signed),补码,一些例题

    本次笔记内容: 03.整数的计算机表示与运算 文章目录 预备知识 数制 数的机器表示 机器字在内存中的组织 字节序(Byte Ordering) 整数表示 计算机中整数的二进制编码方式 无符号数与带符 ...

  9. 已知:Sn= 1+1/2+1/3+…+1/n。显然对于任意一个整数K,当n足够大的时候,Sn大于K。 现给出一个整数K(k大于等于1小于等于15),要求计算出一个最小的n;使得Sn大于K。

    题目描述: 输入 键盘输入 k 输出屏幕输出 n样例输入 1样例输出 2 # include<stdio.h> int main() {int k,i;double Sn=0;scanf( ...

  10. 判断一个整数是否能被7整除或者数中含7

    #include <iostream> #include <algorithm> #include <string> #include <sstream> ...

最新文章

  1. Kafka集群配置说明
  2. Xilinx FIR IP core滤波器系数的重载方法
  3. 活动目录.NET编程Tips
  4. fresco的使用教程
  5. 山东大学为中外学生“学伴”项目不当选项致歉
  6. v-on 事件监听器
  7. Android Hook技术防范漫谈
  8. 外键 级联操作 mysql
  9. SOAP的Could not connect to host in...报错解决方案
  10. SDN的机遇与挑战 让宽带利用率与硬件不再是难题
  11. 互联网公司起名,其实都有套路的!
  12. 彩色证件照片常用的红色、蓝色背景颜色值
  13. mysql中输出100内质数_SQL 打印 100 以内的质数
  14. Spring Boot使用RabbitMQ出现诡异异常:Failed to send reply with payload 'OK',Cannot determine ReplyTo message
  15. 数字图像处理与Python实现-图像几何变换-图像金字塔
  16. debian .iso文件下载地址
  17. 【新知实验室】TRTC体验
  18. Introduce·传播学核心期刊推荐之《现代传播(中国传媒大学学报)》
  19. [python,2018-06-25] 高德纳箭号表示法
  20. 通配符SSL证书 什么是通配符SSL证书 通配符SSL证书的好处

热门文章

  1. IIS HTTP 500 内部服务器错误
  2. 服务器自带raid功能吗,服务器的 RAID 功能介绍
  3. Java list 适配器_适配器基类--万能适配器(BaseAdapter)
  4. ks.cfg配置详解
  5. cdev 结构体、设备号相关知识解析
  6. 基于dpdk的用户态协议栈f-stack实现分析
  7. 版本控制工具——Git常用操作(上)
  8. 用python玩转数据mooc答案_中国大学慕课mooc用Python玩转数据章节测试答案
  9. 全国草地资源类型分布图
  10. C++STL之双端队列Deque