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

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...

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

时间: 2024-09-28 16:55:47

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

【编程题目】判断整数序列是不是二元查找树的后序遍历结果,如果是,构建该二元查找树

判断整数序列是不是二元查找树的后序遍历结果题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果.如果是返回 true,否则返回 false.例如输入 5.7.6.9.11.10.8,由于这一整数序列是如下树的后序遍历结果:8/ \6 10/ \ / \5 7 9 11因此返回 true.如果输入 7.4.6.5,没有哪棵树的后序遍历的结果是这个序列,因此返回 false. 做这个题目的时候最开始傻了,想着从前到后根据数字的大小关系判断.后来幡然醒悟,根据后序遍历的特点.序列最后一

【编程题目】四对括号可以有多少种匹配排列方式?比如两对括号可以有两种:()()和(())

46.搜狐(运算):四对括号可以有多少种匹配排列方式?比如两对括号可以有两种:()()和(()) 跟12个人排高矮的题目差不多. 用 0 表示 “(”,用 1 表示“)” 则需要数字二进制最低8位有 4个1和 4个0,且从低位到高位对1 和 0 计数时,0 出现的次数不能超过 1 出现的次数. /* 46.搜狐(运算): 四对括号可以有多少种匹配排列方式?比如两对括号可以有两种:()()和(()) */ #include <stdio.h> int c_bits(int n) { int re

定义一个由整数组成的数组,然后输入一个整数X,如果X不在此数组中,返回小于X的最大数的位置i和大于X的最小数的位置j

//定义一个由整数组成的数组,然后输入一个整数x,如果X不在此数组中,返回小于X的最大数的位置i和大于X的最小数的位置j: //若X在此数组中,则返回数组中这个数的位置. 源代码: #include<iostream> using namespace std; void main() { int array[]={1,2,3,4,5,6,7,89,45,32,56,78,12,43,90,19};//16个数字 int x; int max=array[0]; int min=array[0]

10.16输入一个字符串,内有数字和非数字字符,如: a123x456 17960? 302tab5876 将其中连续的数字作为一个整数,依次存放到一数组num中。例如123放在num[0]中,456放在num[1]中……统计共有多少个整数,并输出这些数。

10.16输入一个字符串,内有数字和非数字字符,如: a123x456 17960? 302tab5876 将其中连续的数字作为一个整数,依次存放到一数组num中.例如123放在num[0]中,456放在num[1]中--统计共有多少个整数,并输出这些数. #include <stdio.h> int main(){ void search(char * parr, int * pnum); char arr[100],* parr; int num[30],* pnum; parr=arr;

从键盘输入一个整数n(1&lt;n&lt;=9),要用0至n之间不同的三个数构成一个三位数,编写程序统计这样的数共有几个。

代码: 1 import java.util.*; 2 public class Main { 3 public static void main (String [] args) { 4 Scanner cin=new Scanner(System.in); 5 int n=cin.nextInt(); 6 int num=0; 7 for(int b=1;b<=n;b++) { 8 for(int s=0;s<=n;s++) { 9 for(int g=0;g<=n;g++) { 1

为什么迭代器只能被一个集合使用呢 为什么迭代器不能在迭代过程中 ?增删呢 是因为 每次迭代时候 把之前的元素给拿出去了 如果你在操作过程中将下一个迭代元素给拿走了(迭代器不具备自动判断长度功能 她依旧获取的是 操作前的列表长度)此时 无法取到 。 所以迭代器不支持迭代过程进行增删操作

原文地址:https://www.cnblogs.com/classmethond/p/10048515.html

求一个整数中二进制1的个数

题目:求一个整数二进制表示1的个数 第一版: 思路:如果一个整数与1做与运算,结果为1,那么该整数最右边一位是1,否则是0: int NumberOf1(int n) { int count = 0; while (n) { if (n&1)//如果一个整数与1做与运算的结果是1,表示该整数最右边是1,否则是0: { count++; } n = n>>1; } return count; } 缺点:因为代码当中有右移,当是负数的时候,要考虑符号位:如果一个正数,右移之后在最左边补n个

输入一个整数n(0&lt;n&lt;2147483647)打印“*”组成的三角形

描述    输入一个整数n(0<n<2147483647)打印"*"组成的三角形, 如下图    输入    第一行有一个整数n(0<n<2147483647)    输出    "*"组成的三角形 public class Main {     public static void main(String[] arg){         int n = 0;         Scanner scanner = new Scanner(Sys

PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)

PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++:      欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/problem-sets/994805046380707840/problems 目录 (点击对应题目即可进入相应题解--小声BB--) L1-001 Hello World (5 分) L1-002 打印沙漏 (20 分) L1-003 个位数统计 (15 分) L1-004 计算摄氏温度 (5