【七月算法】day11 数组

题目,虽少必做

1975. 最大方阵和

题目描述:

给你一个 n x n 的整数方阵 matrix 。你可以执行以下操作 任意次 :

选择 matrix 中 相邻 两个元素,并将它们都 乘以 -1 。
如果两个元素有 公共边 ,那么它们就是 相邻 的。

你的目的是 最大化 方阵元素的和。请你在执行以上操作之后,返回方阵的 最大 和。

思路:

负数的个数是偶数,则必然所有负数都可以变成正数,累加所有的数(负数变成正数)即可得到答案;

如果负数的个数为奇数,那么累加的的所有数,需要减去2倍的整个数组(负数已经变成正数后)的最小值。

其实我原来用一个vector来存储所有的元素,

在写思路的时候,发现其实我只需要用一个值来确定整个数组的最小值即可。。。

class Solution {
public:
    long long maxMatrixSum(vector<vector<int>>& matrix) {
        int r = matrix.size();
        int c = matrix[0].size();
        long long sum = 0;
        int minv = 110000000;
        int cntneg = 0;
        for (int i = 0; i < r; ++i) {
            for (int j = 0; j < c; ++j) {
                if (matrix[i][j] >= 0) {
                    sum += matrix[i][j];
                    minv = min(matrix[i][j], minv);
                } else {
                    sum += -matrix[i][j];
                    cntneg ++;
                    minv = min(-matrix[i][j], minv);
                }
            }
        }
        if (cntneg%2 == 0) {
            return sum;
        } else {
            sum -=  (long long) 2 *minv ;
        }

        return sum;
    }
};


/*
class Solution {
public:
    long long maxMatrixSum(vector<vector<int>>& matrix) {
        int r = matrix.size();
        int c = matrix[0].size();
        long long sum = 0;
        vector<int> hash;
        int cntneg = 0;
        int flag = 0;
        for (int i = 0; i < r; ++i) {
            for (int j = 0; j < c; ++j) {
                if (matrix[i][j] == 0) {
                    flag = 1;
                } else if (matrix[i][j] >0) {
                    sum += matrix[i][j];
                    hash.push_back(matrix[i][j]);
                } else {
                    hash.push_back(-matrix[i][j]);
                    sum += -matrix[i][j];
                    cntneg ++;
                }
            }
        }
        if (flag || cntneg%2 == 0) {
            return sum;
        } else {
            sort(hash.begin(), hash.end());
            sum -= 2 * hash[0];
        }

        return sum;
    }
};
*/

840. 矩阵中的幻方

题目描述:

3 x 3 的幻方是一个填充有 从 1 到 9  的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。

给定一个由整数组成的row x col 的 grid,其中有多少个 3 × 3 的 “幻方” 子矩阵?(每个子矩阵都是连续的)。

思路:

枚举每一个矩阵中可作为3*3矩阵的起点;

判断是否符合要求:

1、行列对角线的值是否一致

2、每个元素是否都处于1-9,并且只出现一次

满足条件则返回1,否则返回0;

class Solution {
    int check(vector<vector<int>>& grid, int x, int y) {
        int hash[10];
        memset(hash, 0 ,sizeof(hash));
        int val3 = 0;
        int val4 = 0;
        int sum = grid[x][y] + grid[x][y+1] + grid[x][y+2];
        for (int i = 0; i < 3 ; ++ i) {
            int val1 = 0;
            int val2 = 0;
            for (int j = 0; j < 3; ++j) {
                if (grid[x+i][y+j] > 9 || grid[x+i][y+j] < 1 || ++hash[grid[x+i][y+j]] > 1) {
                    return 0;
                }
                val1 += grid[x+i][y+j]; //行
                val2 += grid[x+j][y+i];//列
            }
            val3 += grid[x+i][y+i]; //主对角线
            val4 += grid[x+i][y+2-i]; //副对角线
            if (sum != val1 || sum != val2 ) { //行列不相等
                return 0;
            }
        }
        if (sum != val3 || sum != val4 ) { //行列不相等
            return 0;
        }
        return 1;
    }
public:
    int numMagicSquaresInside(vector<vector<int>>& grid) {
        int ans = 0;
        int r = grid.size();
        int c = grid[0].size();
        for (int i = 0; i < r- 2; ++i) {
            for (int j = 0; j < c - 2; ++j) {
                if (check(grid, i, j)) {
                    ans ++;
                }
            }
        }
        return ans;

    }
};

猜你喜欢

转载自blog.csdn.net/ilovejujube/article/details/125714015